Compare commits
162 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
b7dc0f4057 | |||
0ab9f5f8d2 | |||
1338f29d62 | |||
bc5e2227c8 | |||
654ff82345 | |||
6baeae70e0 | |||
b987972660 | |||
c78526abce | |||
b95e1bb85c | |||
7aa2582129 | |||
3f29d70aba | |||
567d3ddafb | |||
c47f85c639 | |||
40310b4fd7 | |||
f34c274f21 | |||
46e96ee616 | |||
7e60e60e62 | |||
d55ed2d1ca | |||
77c8349c56 | |||
b1c7ed6e29 | |||
e886722d65 | |||
b80b339de3 | |||
efbd05203d | |||
6ca1d76d60 | |||
e1b54056e8 | |||
d5cd610ac7 | |||
91f5ebb376 | |||
ff3b439bda | |||
4672c79181 | |||
83cb07b23c | |||
439a14da1d | |||
d66eef42f6 | |||
337bade549 | |||
eb6503a8ad | |||
1a2e1c767e | |||
858c5479c8 | |||
d36b3d04a8 | |||
da41eb8c6e | |||
775b7a11b4 | |||
23679b86ff | |||
a4f07eb3b3 | |||
6905ab3e56 | |||
05e7f84966 | |||
6e5f840f11 | |||
df37211b7b | |||
bd81e44da0 | |||
37792c5713 | |||
4fb98d9c3c | |||
57a14ec0be | |||
c5d8c26653 | |||
4ff777ee58 | |||
46bb5945c6 | |||
a585d6a32d | |||
b77917fb63 | |||
4673733c4b | |||
f3e63e3cf7 | |||
fb9b3a298c | |||
1539ff120e | |||
20cc592765 | |||
1dd05f63a7 | |||
fe07c87788 | |||
8c58e2a012 | |||
b6b8b1625c | |||
042dbd01ed | |||
7001121a3f | |||
942ec97c7b | |||
8b2edd7ca4 | |||
2e6c3efda2 | |||
2e63856dee | |||
b211ce6804 | |||
4c2a24514d | |||
b07d60bbfc | |||
e8f6f924bd | |||
7a8995f322 | |||
2c88e74798 | |||
2d441cca5d | |||
7e49fb553b | |||
af367561a6 | |||
85bedae639 | |||
bbd198a81b | |||
2a08471c04 | |||
72bdd7a3d0 | |||
bab3cf0c7c | |||
862d4fb571 | |||
27277914c6 | |||
2d3bbe51ed | |||
5288cec97d | |||
09b314c66f | |||
55e134fb1c | |||
9882d983b9 | |||
6fd859a2c1 | |||
4d10b8c73c | |||
0ebc8fe186 | |||
912e0cd1be | |||
3a60720099 | |||
c166a49889 | |||
6fc3bb6777 | |||
d7401f0a4c | |||
6a3273dc72 | |||
0897896713 | |||
1de0284eaa | |||
7c6c3466e9 | |||
3528795b55 | |||
3b95f4c4c4 | |||
2cc387fcce | |||
45bee0a849 | |||
7fd36ffade | |||
5427fa9e17 | |||
ce17f78d59 | |||
1bbdb97a2d | |||
f39e73d2ce | |||
74bc1808a1 | |||
ad251e8c7d | |||
cb3a6f8bb0 | |||
a3285f6e5d | |||
36502f8ae3 | |||
21109ffcf1 | |||
bcd4b88319 | |||
714ef6493a | |||
01b2ee088b | |||
2ed96d89f9 | |||
cc71d9e30b | |||
4fd7faa636 | |||
d2c19ed2b4 | |||
63df7749fa | |||
e9eb22f514 | |||
e57e45e40b | |||
1ed3ba7933 | |||
3e2479c095 | |||
bc7e8acb74 | |||
8770148cad | |||
6fc6a09040 | |||
a72fd6a309 | |||
82f39020cf | |||
1842921b2c | |||
ab11c954d9 | |||
177864bd13 | |||
ed986aa4ea | |||
45bf3d9717 | |||
c1df1c9fd8 | |||
a7ae64e3c7 | |||
6cb5f802af | |||
a8b20b87aa | |||
201e7f15df | |||
f040f31d05 | |||
9e2d82fc78 | |||
1a5c02a27e | |||
e5a4e33ebd | |||
fae423fb54 | |||
e97bd3ed2d | |||
2c540b1f43 | |||
6982971796 | |||
3c7c534ded | |||
262e49ad6b | |||
502bea814e | |||
fa784d619c | |||
977161cda1 | |||
dc2b27ca51 | |||
abd2137906 | |||
ff95a84130 | |||
f384961808 | |||
81dd6ce55a |
1
AUTHORS
1
AUTHORS
@ -1,3 +1,4 @@
|
|||||||
Vreixo Formoso
|
Vreixo Formoso
|
||||||
Mario Danic
|
Mario Danic
|
||||||
|
Vladimir Serbinenko
|
||||||
Thomas Schmitt
|
Thomas Schmitt
|
||||||
|
72
ChangeLog
72
ChangeLog
@ -1,4 +1,73 @@
|
|||||||
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
|
libisofs-1.3.4.tar.gz Thu Dec 12 2013
|
||||||
|
===============================================================================
|
||||||
|
* Giving sort weight 2 as default to El Torito boot images
|
||||||
|
* Encoding HFS+ names in UTF-16 rather than UCS-2.
|
||||||
|
|
||||||
|
libisofs-1.3.2.tar.gz Wed Aug 07 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent
|
||||||
|
call of iso_init() would try to dereference.
|
||||||
|
* The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
|
||||||
|
rather than 2 exp 31 - 1 to - 2 exp 31
|
||||||
|
|
||||||
|
libisofs-1.3.0.tar.gz Fri May 17 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
|
||||||
|
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
|
||||||
|
represented by 0-bytes rather than ASCII '0' digits.
|
||||||
|
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
|
||||||
|
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
|
||||||
|
* New option bits with el_torito_set_isolinux_options() and
|
||||||
|
iso_write_opts_set_system_area() to control GRUB2 patching of
|
||||||
|
boot image and MBR.
|
||||||
|
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
|
||||||
|
|
||||||
|
libisofs-1.2.8.tar.gz Mon Mar 18 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Image size prediction altered the pointers to MD5 of data files
|
||||||
|
which stem from a previous session.
|
||||||
|
* Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL.
|
||||||
|
* New API call iso_image_get_pvd_times().
|
||||||
|
|
||||||
|
libisofs-1.2.6.tar.gz Tue Jan 08 2013
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Appended partitions did not obey cylinder alignment
|
||||||
|
* Bug fix: Non-zero partition offset zeroized the MBR copies of GPT partition
|
||||||
|
table entries
|
||||||
|
* Bug fix: Isohybrid production without any boot image led to SIGSEGV by NULL
|
||||||
|
* Bug fix: Prevented a memory fault when reading damaged Rock Ridge information
|
||||||
|
|
||||||
|
libisofs-1.2.4.tar.gz Fri Jul 20 2012
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: Memory corruption when reading bootable image that was truncated
|
||||||
|
before the storage location of the boot catalog
|
||||||
|
* Bug fix: Symbol iso_fs_global_id was missing in libisofs.ver.
|
||||||
|
* Bug fix: Volume descriptors of Joliet and ISO 9660:1999 beared non-zero
|
||||||
|
Effective Date, involuntarily restricting the early end of
|
||||||
|
their lifetime.
|
||||||
|
* Bug fix: File Structure Version field of ISO 9660:1999 Enhanced Volume
|
||||||
|
Descriptor was 1 instead of 2.
|
||||||
|
* Bug fix: The separator dot of Joliet names was byte swapped on big-endian
|
||||||
|
machines.
|
||||||
|
* Bug fix: Joliet name comparison was done as signed bytes and thus produced
|
||||||
|
a peculiar sorting order.
|
||||||
|
* Bug fix: Partition cylinder alignment worked only if both, El Torito and
|
||||||
|
application provided system area data were present.
|
||||||
|
* New API function iso_write_opts_set_hfsplus
|
||||||
|
* New API functions iso_hfsplus_xinfo_func(), iso_hfsplus_xinfo_new(), and
|
||||||
|
new struct iso_hfsplus_xinfo_data.
|
||||||
|
* New API call iso_write_opts_set_hfsp_serial_number()
|
||||||
|
* New API calls iso_image_hfsplus_bless and iso_image_hfsplus_get_blessed(),
|
||||||
|
and new public enum IsoHfsplusBlessings.
|
||||||
|
* New API calls so_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp()
|
||||||
|
* New API call iso_write_opts_set_hfsp_block_size()
|
||||||
|
* New API call iso_tree_resolve_symlink()
|
||||||
|
* New system area sub type CHRP with iso_write_opts_set_system_area()
|
||||||
|
* New option bits 2 to 8 for GPT and APM with el_torito_set_isolinux_options()
|
||||||
|
* New flag bit with iso_node_set_attrs() to protect namespace "isofs"
|
||||||
|
* New IsoHideNodeFlag value LIBISO_HIDE_ON_HFSPLUS
|
||||||
|
|
||||||
|
libisofs-1.2.2.tar.gz Mon Apr 02 2012
|
||||||
===============================================================================
|
===============================================================================
|
||||||
* New API call iso_write_opts_set_rr_reloc()
|
* New API call iso_write_opts_set_rr_reloc()
|
||||||
* Bug fix: Directory name mapping to ISO level 1 was too liberal if
|
* Bug fix: Directory name mapping to ISO level 1 was too liberal if
|
||||||
@ -7,7 +76,6 @@ bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
|
|||||||
* Improved standards compliance for ISO level 1 names with partly relaxed
|
* Improved standards compliance for ISO level 1 names with partly relaxed
|
||||||
constraints.
|
constraints.
|
||||||
|
|
||||||
|
|
||||||
libisofs-1.2.0.tar.gz Sat Jan 28 2012
|
libisofs-1.2.0.tar.gz Sat Jan 28 2012
|
||||||
===============================================================================
|
===============================================================================
|
||||||
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
|
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
|
||||||
|
@ -66,6 +66,11 @@ libisofs_libisofs_la_SOURCES = \
|
|||||||
libisofs/rockridge_read.c \
|
libisofs/rockridge_read.c \
|
||||||
libisofs/joliet.h \
|
libisofs/joliet.h \
|
||||||
libisofs/joliet.c \
|
libisofs/joliet.c \
|
||||||
|
libisofs/hfsplus.h \
|
||||||
|
libisofs/hfsplus.c \
|
||||||
|
libisofs/hfsplus_decompose.c \
|
||||||
|
libisofs/hfsplus_classes.c \
|
||||||
|
libisofs/hfsplus_case.c \
|
||||||
libisofs/eltorito.h \
|
libisofs/eltorito.h \
|
||||||
libisofs/eltorito.c \
|
libisofs/eltorito.c \
|
||||||
libisofs/system_area.h \
|
libisofs/system_area.h \
|
||||||
|
5
README
5
README
@ -4,7 +4,10 @@
|
|||||||
|
|
||||||
Released under GPL (see COPYING file for details).
|
Released under GPL (see COPYING file for details).
|
||||||
|
|
||||||
Copyright (C) 2008 - 2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
Copyright (C) 2008 - 2013 Vreixo Formoso,
|
||||||
|
Mario Danic,
|
||||||
|
Vladimir Serbinenko,
|
||||||
|
Thomas Schmitt
|
||||||
|
|
||||||
libisofs is part of the libburnia project (libburnia-project.org)
|
libisofs is part of the libburnia project (libburnia-project.org)
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
14
configure.ac
14
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
|
AC_INIT([libisofs], [1.3.4], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ dnl
|
|||||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
LIBISOFS_MAJOR_VERSION=1
|
LIBISOFS_MAJOR_VERSION=1
|
||||||
LIBISOFS_MINOR_VERSION=2
|
LIBISOFS_MINOR_VERSION=3
|
||||||
LIBISOFS_MICRO_VERSION=2
|
LIBISOFS_MICRO_VERSION=4
|
||||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||||
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
|||||||
|
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||||
# 2012.01.28 development jump has not yet happened
|
# 2013.12.12 development jump has not yet happened
|
||||||
# SONAME = 64 - 58 = 6 . Library name = libisofs.6.58.0
|
# SONAME = 76 - 70 = 6 . Library name = libisofs.6.70.0
|
||||||
LT_CURRENT=64
|
LT_CURRENT=76
|
||||||
LT_AGE=58
|
LT_AGE=70
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
|
@ -15,9 +15,13 @@ specifications, some is just rumor which happens to work (maybe not even that).
|
|||||||
|
|
||||||
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
|
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
|
||||||
|
|
||||||
MBR, for PC-BIOS x86 from (pseudo-) hard disk
|
Boot Info Table and GRUB2 Boot Info
|
||||||
- SYSLINUX isohybrid MBR
|
|
||||||
- GRUB2 grub-mkrescue MBR.
|
Master Boot Record (MBR), for PC-BIOS x86 from (pseudo-) hard disk
|
||||||
|
|
||||||
|
Apple Partition Map (APM), for more modern Mac
|
||||||
|
|
||||||
|
GUID Partition Table (GPT), for EFI from (pseudo-) hard disk
|
||||||
|
|
||||||
MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
||||||
|
|
||||||
@ -25,6 +29,16 @@ DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
|||||||
|
|
||||||
SUN Disk Label and boot images, for SUN SPARC
|
SUN Disk Label and boot images, for SUN SPARC
|
||||||
|
|
||||||
|
PowerPC Reference Platform (PReP), for IBM PowerPC
|
||||||
|
|
||||||
|
Common Hardware Reference Platform (CHRP), for IBM PowerPC
|
||||||
|
|
||||||
|
Combinations of boot mechanisms:
|
||||||
|
- SYSLINUX isohybrid MBR
|
||||||
|
- SYSLINUX isohybrid for MBR, UEFI and x86-Mac
|
||||||
|
- GRUB2 grub-mkrescue MBR
|
||||||
|
>>> Mac and/or PowerPC bootable GRUB2 image with HFS+/FAT, APM,
|
||||||
|
EFI GPT partition, PreP MBR partition, mountable FAT partition
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -36,7 +50,6 @@ Sources:
|
|||||||
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
||||||
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
||||||
libisofs/eltorito.[ch] by Vreixo Formoso.
|
libisofs/eltorito.[ch] by Vreixo Formoso.
|
||||||
man mkisofs by Joerg Schilling.
|
|
||||||
|
|
||||||
|
|
||||||
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
|
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
|
||||||
@ -44,7 +57,13 @@ with arbitrary content. This prescription is obeyed by PC-BIOS systems only
|
|||||||
if the ISO 9660 image is presented on CD, DVD or BD media.
|
if the ISO 9660 image is presented on CD, DVD or BD media.
|
||||||
In this case the El Torito Boot record is the starting point of booting.
|
In this case the El Torito Boot record is the starting point of booting.
|
||||||
|
|
||||||
The Boot Record is a ECMA-119 Volume Descriptor which is eventually located
|
After the System Area, an ISO 9660 image usually has three distinct block
|
||||||
|
intervals for:
|
||||||
|
- Volume descriptors (Primary Volume Descriptor, Boot Record, Joliet, ...)
|
||||||
|
- 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
|
at 2 kB block number 17 (decimal). Its content points to the location of the
|
||||||
Boot Catalog.
|
Boot Catalog.
|
||||||
The format is described in part by ECMA-119 8.2 "Boot Record" and further
|
The format is described in part by ECMA-119 8.2 "Boot Record" and further
|
||||||
@ -101,7 +120,7 @@ Defined by El Torito are:
|
|||||||
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
||||||
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
||||||
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
|
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
|
||||||
Further in use by GRUB2 is:
|
Further in use by GRUB2 and ISOLINUX is:
|
||||||
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
|
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
|
||||||
Intel ia64 Itanium and possibly with newer Apple machines.
|
Intel ia64 Itanium and possibly with newer Apple machines.
|
||||||
|
|
||||||
@ -219,10 +238,22 @@ Byte Range | Value | Meaning
|
|||||||
12 - 31 | sel_crit | "Vendor unique selection criteria."
|
12 - 31 | sel_crit | "Vendor unique selection criteria."
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Boot Info Table and GRUB2 Boot Info
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
man mkisofs by Joerg Schilling
|
||||||
|
Mail conversations with Vladimir Serbinenko.
|
||||||
|
|
||||||
|
|
||||||
The boot image file content is mostly opaque to the ISO 9660 image generator.
|
The boot image file content is mostly opaque to the ISO 9660 image generator.
|
||||||
Nevertheless there is a tradition named "Boot Info Table" which prescribes
|
Nevertheless there is a tradition named "Boot Info Table" which prescribes
|
||||||
to write information into byte fields of the boot image file content.
|
to write information into byte fields of the boot image file content.
|
||||||
|
Recent versions of GRUB2 expect a similar patching which has no name yet.
|
||||||
|
For now let's call it "GRUB2 Boot Info"
|
||||||
|
|
||||||
There are no general means known how a producer of ISO 9660 images could
|
There are no general means known how a producer of ISO 9660 images could
|
||||||
detect the need for Boot Info Table production.
|
detect the need for Boot Info Table production.
|
||||||
It rather needs a hint from the user who has to know whether the boot image
|
It rather needs a hint from the user who has to know whether the boot image
|
||||||
@ -231,24 +262,36 @@ The Boot Info Table begins at byte 8 of the boot image content.
|
|||||||
|
|
||||||
Byte Range | Value | Meaning
|
Byte Range | Value | Meaning
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor
|
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor.
|
||||||
| | This is the session start LBA + 16.
|
| | This is the session start LBA + 16.
|
||||||
| |
|
| |
|
||||||
12 - 15 | file_lba | Block address of the start of the boot image file
|
12 - 15 | file_lba | Block address of the start of the boot image file
|
||||||
| | content.
|
| | content. Block size is 2048.
|
||||||
| |
|
| |
|
||||||
16 - 19 | file_len | Number of bytes in boot image file content.
|
16 - 19 | file_len | Number of bytes in boot image file content.
|
||||||
| |
|
| |
|
||||||
20 - 23 | checksum | Little-endian: The sum of all 32-bit words of the
|
20 - 23 | checksum | The sum of all 32-bit words of the file content
|
||||||
| | file content from byte 64 to file end.
|
| | from byte 64 to file end.
|
||||||
| |
|
| |
|
||||||
24 - 63 | 0 | Reserved
|
24 - 63 | 0 | Reserved
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
All numbers are stored little-endian.
|
||||||
|
|
||||||
|
GRUB2 Boot Info represents a particular block address inside the boot image.
|
||||||
|
It may well be combined with Boot Info Table. See GRUB2 script grub-mkrescue
|
||||||
|
use of xorrisofs options -boot-info-table and --grub2-boot-info.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
2548 -2555 | grub2_adr | Block address of the start of the boot image file
|
||||||
|
| | content plus 5. Block size is 512.
|
||||||
|
| | 64 bit Little-endian.
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
MBR
|
Master Boot Record (MBR)
|
||||||
for PC-BIOS x86 from (pseudo-) hard disk
|
for PC-BIOS x86 from (pseudo-) hard disk
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
@ -343,92 +386,244 @@ See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
|
|||||||
and http://libburnia-project.org/wiki/PartitionOffset for examples with
|
and http://libburnia-project.org/wiki/PartitionOffset for examples with
|
||||||
program xorriso.
|
program xorriso.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Apple Partition Map (APM)
|
||||||
|
for Apple Macs introduced since 2000 and more computer-like than iPad
|
||||||
|
from CD and often from (pseudo-) hard disk
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
http://mjg59.dreamwidth.org/11285.html
|
||||||
|
http://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h (typedef struct Block0)
|
||||||
|
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
|
||||||
|
syslinux-4.05/utils/isohybrid.c
|
||||||
|
Mail conversations with Vladimir Serbinenko.
|
||||||
|
|
||||||
|
|
||||||
|
APM has an adjustable block size. Because the ISO images shall always work
|
||||||
|
on optical media, and in order to make room for the header block of an
|
||||||
|
additional GPT, only block size 2048 is considered here.
|
||||||
|
The role of APM in the boot process is to guide the firmware to a
|
||||||
|
HFS+ filesystem.
|
||||||
|
|
||||||
|
Block0 of an APM begins at byte 0 of the medium. Thus it collides with MBR and
|
||||||
|
other boot sector formats. By lucky coincidence it is possible to compose
|
||||||
|
a mock-up of a Block0 which is acceptable to firmware which expects APM,
|
||||||
|
and is also harmless x86 machine code with no negative side effects.
|
||||||
|
So it is possible to combine APM with an especially prepared MBR.
|
||||||
|
|
||||||
|
The layout of a Block0 of an APM is:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (all numbers are stored big endian)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 1 | sig | Signature 0x45 = 'E' , 0x52 = 'R'
|
||||||
|
2 - 3 | block_size | 0x0800 = 2048
|
||||||
|
4 - 7 | block_count| Number of blocks covered by APM
|
||||||
|
| | Often some x86-harmless dummy. E.g. 0x9090 = 37008
|
||||||
|
| | or 0xeb02ffff = 3,942,842,367
|
||||||
|
8 - 9 | dev_type | obscure: "device type"
|
||||||
|
10 - 11 | dev_id | obscure: "device id"
|
||||||
|
12 - 15 | drv_data | obscure: "driver data"
|
||||||
|
16 - 17 | drv_count | obscure: "driver descriptor count"
|
||||||
|
18 - 81 | drv_map | obscure: "driver descriptor table"
|
||||||
|
| | with 8 entries of 16 bytes each
|
||||||
|
82 - 511 | reserved |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
The SYSLINUX program isohybrid.c overwrites the first 32 bytes of this
|
||||||
|
layout by its dummy values. It uses the small block_count 0x00009090 and
|
||||||
|
sets all bytes up to 31 to 0.
|
||||||
|
The libisofs HFS+ extension by Vladimir Serbinenko overwrites only the
|
||||||
|
first 8 bytes. It uses the large block_count 0xeb02ffff.
|
||||||
|
|
||||||
|
Block0 and the following APM entries each occupy 1 block of the announced size.
|
||||||
|
|
||||||
|
The first APM entry describes the range from its own start to the end of the
|
||||||
|
last APM entry. Each of the other APM entries describes a partition.
|
||||||
|
|
||||||
|
The layout of an Apple partition map entry is:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (all numbers are stored big endian)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 1 | sig | Signature 0x50 = 'P' , 0x4d = 'M'
|
||||||
|
2 - 3 | reserved |
|
||||||
|
4 - 7 | map_entries| Number of partition entries.
|
||||||
|
| | All entries show the same number.
|
||||||
|
8 - 11 | start_block| "physical block start of partition"
|
||||||
|
12 - 15 | block_count| "physical block count of partition"
|
||||||
|
16 - 47 | name | Partition name
|
||||||
|
48 - 79 | type | Type string
|
||||||
|
80 - 83 | lb_start | Logical block start = 0
|
||||||
|
84 - 87 | lb_count | Logical block count (same as block_count)
|
||||||
|
88 - 91 | flags | Status flags
|
||||||
|
| | bit0= entry is valid
|
||||||
|
| | bit1= entry is allocated
|
||||||
|
| | bit4= partition is readable
|
||||||
|
| | bit5= partition is writable
|
||||||
|
| | bit30= automatic mount (legacy Mac)
|
||||||
|
92 - 95 | boot_block | Logical start block number of boot code = 0
|
||||||
|
96 - 99 | boot_bytes | Number of bytes in boot code = 0
|
||||||
|
100 - 119 | | More boot code stuff = 0
|
||||||
|
120 - 135 | processor | "processor type" = 0
|
||||||
|
136 - 511 | reserved |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
For the first APM entry (byte 0x0800), the following values apply:
|
||||||
|
map_entries = number of APM entries, including itself. E.g. 4.
|
||||||
|
start_block = 1
|
||||||
|
block_count = map_entries
|
||||||
|
name = "Apple"
|
||||||
|
type = "Apple_partition_map"
|
||||||
|
flags = 3
|
||||||
|
|
||||||
|
libisofs uses APM to mark a HFS+ filesystem partition within an ISO 9660 image.
|
||||||
|
Usually the APM has 3 more entries after the first entry:
|
||||||
|
|
||||||
|
Entry 2 (byte 0x1000) describes the block interval from ISO image start to
|
||||||
|
the start of the HFS+ filesystem meta data.
|
||||||
|
start_block = 16
|
||||||
|
block_count = start_of_hfs - 16
|
||||||
|
name = "Gap0"
|
||||||
|
type = "ISO9660_data"
|
||||||
|
flags = 0x13
|
||||||
|
|
||||||
|
Entry 3 (byte 0x1800) describes the interval from the start of the HFS+ meta
|
||||||
|
data to the end of the HFS+ data at the end of its partition. This includes all
|
||||||
|
content blocks of the data files in the ISO image.
|
||||||
|
start_block = start_of_hfs
|
||||||
|
block_count = end_of_hfs - start_of_hfs
|
||||||
|
name = "HFSPLUS_Hybrid"
|
||||||
|
type = "Apple_HFS"
|
||||||
|
flags = 0x40000013
|
||||||
|
|
||||||
|
Entry 4 (byte 0x2000) describes the interval from the end of the HFS+
|
||||||
|
partition to the end of the ISO image. It is possible that this interval is
|
||||||
|
empty. In this case, no fourth APM entry will be written.
|
||||||
|
start_block = end_of_hfs
|
||||||
|
block_count = end_of_iso - end_of_hfs
|
||||||
|
name = "Gap1"
|
||||||
|
type = "ISO9660_data"
|
||||||
|
flags = 0x13
|
||||||
|
|
||||||
|
|
||||||
|
>>> Open questions:
|
||||||
|
>>> What HFS+ blessings are needed for booting ?
|
||||||
|
>>> What files need what HFS creator and type settings ?
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
SYSLINUX Isohybrid MBR
|
GUID Partition Table (GPT)
|
||||||
|
for alternative mountability paths
|
||||||
|
and for EFI booting of some Apple Macs from (pseudo-) hard disk
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
syslinux-3.72/utils/isohybrid , a perl script by H. Peter Anvin = hpa.
|
http://mjg59.dreamwidth.org/11285.html
|
||||||
Mailing list conversations with hpa.
|
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
|
||||||
|
http://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||||
|
http://en.wikipedia.org/wiki/GUID
|
||||||
|
|
||||||
|
|
||||||
An isohybrid MBR directs the booting BIOS to an ISOLINUX boot image which
|
GPT is the partition map format of EFI, a successor of PC-BIOS.
|
||||||
is also the target of an El Torito boot catalog entry.
|
Block size is always 512. GPT consists of a header block at block address 1 and
|
||||||
For that purpose one has to take an MBR template and has to set a few bytes
|
a partition table near the start of the medium. This is called the primary GPT.
|
||||||
to values which sufficiently describe the ISO image and the boot image file.
|
There is a backup copy of header and table near the end of the medium.
|
||||||
|
|
||||||
Words are composed little-endian style.
|
GPT is particularly designed to co-exist with MBR. If it is present, then the
|
||||||
|
booting firmware may or may not prefer it over the MBR partition table.
|
||||||
|
GPT can co-exist with APM if APM block size is at least 1024. In this case,
|
||||||
|
the primary partition table will begin after the last APM entry block.
|
||||||
|
|
||||||
Byte Range | Value | Meaning
|
The header block format is:
|
||||||
|
Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
0 - 431 | = opaque = | Syslinux machine code provided by MBR template
|
0 - 7 | sig | Signature "EFI PART" (with no trailing zero)
|
||||||
| |
|
8 - 11 | revision | Revision = {0x00, 0x00, 0x01, 0x00} meaning "1.0"
|
||||||
432 - 439 | hd_bootlba | Address of the ISOLINUX boot image file in the
|
12 - 15 | head_size | Header size = 0x5c = 92
|
||||||
| | ISO image. Counted in 512 byte blocks.
|
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0
|
||||||
| |
|
20 - 23 | reserved | = 0
|
||||||
440 - 443 | mbr_id | Random number
|
24 - 31 | curr_lba | Location of this header block = 1
|
||||||
444 - 445 | 0 | Padding
|
32 - 39 | back_lba | Location of header backup block. See below.
|
||||||
| |
|
40 - 47 | first_lba | First usable LBA for partitions
|
||||||
446 - 509 | ========== | Partition table
|
48 - 55 | last_lba | Last usable LBA for partitions
|
||||||
| |
|
56 - 71 | guid | Disk GUID, Random
|
||||||
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
72 - 79 | part_start | Partition entries start
|
||||||
| | starting at LBA 0. I.e. contrary to tradition.
|
| | Normally this is 2. But to co-exist with APM, it
|
||||||
| | See above for partition table entry format.
|
| might become some other number up to 62.
|
||||||
| |
|
80 - 83 | entry_count| Number of partition entries
|
||||||
462 - 509 | 0 | Unused partition entries 2 to 4
|
84 - 87 | entry_size | Size of a partition entry = 0x80 = 128
|
||||||
510 - 511 | 0xaa55 | MBR signature
|
88 - 91 | p_arr_crc | CRC-32 of the partition array
|
||||||
|
92 - 511 | reserved | Must be 0
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
The CRC-32 algorithm can be characterized as follows:
|
||||||
|
The generating polynomial has the bit representation 0x104c11db7.
|
||||||
|
The seed value for a bit shifting division algorithm is 0x46af6449. It is
|
||||||
|
chosen so that the CRC of 0 bytes of input is 0x00000000.
|
||||||
|
The least significant bits of input bytes get processed first. I.e. bit0 of
|
||||||
|
the last input byte gets mapped to x exp (7 + 32), bit7 of this byte gets
|
||||||
|
mapped to x exp (0 + 32).
|
||||||
|
The resulting division residue gets bitwise mirrored. E.g. bit0 becomes bit31,
|
||||||
|
bit1 becomes bit30, and so on. Further it gets exored with 0xffffffff.
|
||||||
|
|
||||||
|
A GUID consists of a 32-bit integer, two 16-bit integers, and an array of
|
||||||
|
8 bytes. The integers are to be stored big-endian.
|
||||||
|
A globally registered class of GUID are the partition type GUIDs.
|
||||||
|
This example uses two of them
|
||||||
|
Basic data partition: a2 a0 d0 eb , e5 b9 , 33 44 , 87 c0 68 b6 b7 26 99 c7
|
||||||
|
HFS+ partition : 00 53 46 48 , 00 00 , aa 11 , aa 11 00 30 65 43 ec ac
|
||||||
|
EFI System partition: 28 73 2a c1 , 1f f8 , d2 11 , ba 4b 00 a0 c9 3e c9 3b
|
||||||
|
Note that the wikipedia list shows the first 32-bit word and the next two
|
||||||
|
16-bit words in little-endia interpretation.
|
||||||
|
|
||||||
|
The partition table is an array of entries. Each has a size of 128 bytes.
|
||||||
|
A partition table entry looks like:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (numbers are stored little endian)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 15 | type_guid | Partition type GUID
|
||||||
|
16 - 31 | part_guid | Unique partition GUID, Random
|
||||||
|
32 - 39 | start_lba | First LBA
|
||||||
|
40 - 47 | end_lba | Last LBA (inclusive)
|
||||||
|
48 - 55 | flags | Attribute flags
|
||||||
|
| | bit0= "System Partition" Do not alter.
|
||||||
|
| | bit2= Legacy BIOS bootable (MBR partition type 0x80)
|
||||||
|
| | bit60= read-only
|
||||||
|
56 - 127 | name | Characters encoded as UTF-16LE. Padded by 0-bytes.
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
hpa about MBR templates and partition table filesystem types:
|
About header field "Location of header backup block":
|
||||||
|
|
||||||
"[MBR templates] are available in the Syslinux build tree under the names:
|
Near to the end of the image, after any data blocks which might be of interest
|
||||||
mbr/isohdp[fp]x*.bin
|
for the filesystems covered by GPT partitions, there is a backup of partition
|
||||||
The default probably should be mbr/isohdppx.bin, but it's ultimately up
|
table and header block.
|
||||||
to the user.
|
The header block is supposed to mark the end of the usable medium. But libisofs
|
||||||
[...]
|
may have the need to add more data.
|
||||||
Note: the filesystem type is largely arbitrary, in theory it can be any
|
The partition table is stored directly before the header block. So it will
|
||||||
value other than 0x00, 0x05, 0x0f, 0x85, 0xee, or 0xef. 0x17 ("Windows
|
normally not begin at a 2 KiB block start.
|
||||||
IFS Hidden") seems safeish, some people believe 0x83 (Linux) is better.
|
|
||||||
"
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
The content of the backup partition table is the same as the one of the
|
||||||
|
primary table.
|
||||||
|
The backup header differs from the primary header by
|
||||||
GRUB2 grub-mkrescue MBR
|
Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
||||||
|
|
||||||
Sources:
|
|
||||||
Mailing list conversations with Vladimir Serbinenko.
|
|
||||||
|
|
||||||
|
|
||||||
The MBR file that is used with GRUB2 script grub-mkrescue needs only a
|
|
||||||
partition table entry which describes the image size.
|
|
||||||
|
|
||||||
Byte Range | Value | Meaning
|
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template
|
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0.
|
||||||
| |
|
| | Is recomputed after the following changes.
|
||||||
446 - 509 | ========== | Partition table
|
24 - 31 | curr_lba | Location of this header block.
|
||||||
| |
|
| | Shows own block address.
|
||||||
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
32 - 39 | back_lba | Location of header backup block.
|
||||||
| | Peculiar is the start offset of 1 block.
|
| | Points to primary header block = 1
|
||||||
| | This prevents mounting of the partition.
|
72 - 79 | part_start | Partition entries start.
|
||||||
| | See above for partition table entry format.
|
| | Points to start of backup partition table.
|
||||||
| |
|
|
||||||
462 - 509 | 0 | Unused partition entries 2 to 4
|
|
||||||
510 - 511 | 0xaa55 | MBR signature
|
|
||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
Vladimir Serbinenko about the partition table entry:
|
|
||||||
"Currently we use first and not last entry. You need to:
|
An EFI System partition usually contains the same data blocks as the El Torito
|
||||||
1) Zero-fill 446-510
|
boot image for EFI. It is used for booting some Macs from (pseudo-) hard disk.
|
||||||
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
|
|
||||||
"
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -715,6 +910,41 @@ Byte Range | Value | Meaning
|
|||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
PowerPC Reference Platform (PReP)
|
||||||
|
for IBM PowerPC
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
Mail conversations with Vladimir Serbinenko.
|
||||||
|
|
||||||
|
|
||||||
|
PReP boots via a MBR partition containing only raw ELF and having type 0x41.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Common Hardware Reference Platform (CHRP)
|
||||||
|
for IBM PowerPC
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
Mail conversations with Vladimir Serbinenko.
|
||||||
|
http://stuff.mit.edu/afs/sipb/contrib/doc/specs/protocol/chrp/chrp1_7a.pdf
|
||||||
|
|
||||||
|
CHRP is marked by an MBR partition entry of type 0x96 spanning the whole
|
||||||
|
ISO 9660 image.
|
||||||
|
|
||||||
|
The specs in chrp1_7a.pdf promise that CHRP also recognizes ISO 9660 file
|
||||||
|
systems on unpartitioned disks. (See 11.1.1. Media Layout Format)
|
||||||
|
|
||||||
|
Vladimir Serbinenko stated:
|
||||||
|
PReP boot may be preferable. At least it can co-exist with other partitions
|
||||||
|
in the ISO image [without causing overlapping between partitions].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
>>> ??? HP-PA
|
>>> ??? HP-PA
|
||||||
@ -723,5 +953,514 @@ Byte Range | Value | Meaning
|
|||||||
|
|
||||||
>>> ??? DEC Alpha
|
>>> ??? DEC Alpha
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Combinations of boot mechanisms
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
SYSLINUX Isohybrid MBR
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
syslinux-3.72/utils/isohybrid , a perl script by H. Peter Anvin = hpa.
|
||||||
|
Mailing list conversations with hpa.
|
||||||
|
|
||||||
|
|
||||||
|
An isohybrid MBR directs the booting BIOS to an ISOLINUX boot image which
|
||||||
|
is also the target of an El Torito boot catalog entry.
|
||||||
|
For that purpose one has to take an MBR template and has to set a few bytes
|
||||||
|
to values which sufficiently describe the ISO image and the boot image file.
|
||||||
|
|
||||||
|
Words are composed little-endian style.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 431 | = opaque = | Syslinux machine code provided by MBR template
|
||||||
|
| |
|
||||||
|
432 - 439 | hd_bootlba | Address of the ISOLINUX boot image file in the
|
||||||
|
| | ISO image. Counted in 512 byte blocks.
|
||||||
|
| |
|
||||||
|
440 - 443 | mbr_id | Random number
|
||||||
|
444 - 445 | 0 | Padding
|
||||||
|
| |
|
||||||
|
446 - 509 | ========== | Partition table
|
||||||
|
| |
|
||||||
|
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
||||||
|
| | rounded up to the next full MiB. The partition starts
|
||||||
|
| | at LBA 0. (I.e. contrary to tradition.)
|
||||||
|
| | See above for partition table entry format.
|
||||||
|
| |
|
||||||
|
462 - 509 | 0 | Unused partition entries 2 to 4
|
||||||
|
510 - 511 | 0xaa55 | MBR signature
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
The ISO image file gets padded up to the next full MiB.
|
||||||
|
|
||||||
|
hpa about MBR templates and partition table filesystem types:
|
||||||
|
|
||||||
|
"[MBR templates] 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.
|
||||||
|
[...]
|
||||||
|
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.
|
||||||
|
"
|
||||||
|
|
||||||
|
|
||||||
|
>>> SYSLINUX isohybrid for MBR, UEFI and x86-Mac
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
http://mjg59.dreamwidth.org/11285.html
|
||||||
|
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
|
||||||
|
http://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h (typedef struct Block0)
|
||||||
|
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
|
||||||
|
http://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||||
|
http://en.wikipedia.org/wiki/GUID
|
||||||
|
syslinux-4.05/utils/isohybrid.c
|
||||||
|
|
||||||
|
>>> Motivation: What systems will use the additional data ? amd64 UEFI ?
|
||||||
|
|
||||||
|
This is a very condensed format which exposes a lot of entry points for boot
|
||||||
|
firmware. It disobeys some of the prescriptions in the previous chapter.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
-------------- | ---------- | -------------------------------------------------
|
||||||
|
0 - 511 | mbr | Isohybrid MBR pointing to x86 boot image file,
|
||||||
|
| | with three entries in its partition map.
|
||||||
|
| | It shares its first 32 bytes with apm_head.
|
||||||
|
0 - 31 | apm_head | Mock-up of the start of the first block of
|
||||||
|
| | an Apple Partition Map (APM).
|
||||||
|
446 - 461 | mbr_entry1 | Partition table entry 1 describing the size of
|
||||||
|
| | the ISO image plus the backup GPT, padded up to
|
||||||
|
| | the next full MiB.
|
||||||
|
462 - 477 | mbr_entry2 | Entry 2 describing the EFI VFAT boot image.
|
||||||
|
478 - 493 | mbr_entry3 | Entry 3 describing the HFS+ boot image.
|
||||||
|
| |
|
||||||
|
512 - 1023 | gpt_head | GPT header describing the GPT partition array.
|
||||||
|
1024 - 2047 | unused |
|
||||||
|
2048 - 4095 | apm_entry1 | APM entry 1 describing APM entries 1 to 3.
|
||||||
|
4096 - 6143 | apm_entry2 | APM entry 2 describing the EFI VFAT boot image.
|
||||||
|
6144 - 8195 | apm_entry3 | APM entry 3 describing the HFS+ boot image.
|
||||||
|
8192 - 8319 | gpt_entry1 | GPT partition entry 1 for the ISO image size.
|
||||||
|
8320 - 8447 | gpt_entry2 | GPT partition entry 2 for EFI VFAT boot image,
|
||||||
|
8448 - 8575 | gpt_entry3 | GPT partition entry 3 for the HFS+ boot image.
|
||||||
|
8576 - 24575 | gtp_empty | Empty GPT partition entries 4 to 128.
|
||||||
|
24576 - 32767 | unused |
|
||||||
|
32768 - 34815 | iso_pvd | ISO 9660 superblock
|
||||||
|
34816 - 36863 | el_torito | EL Torito boot block pointing to a boot catalog
|
||||||
|
| | with entries for the MBR boot image (platform id
|
||||||
|
| | 0x00), and for the two other boot images
|
||||||
|
| | (platform id 0xef)
|
||||||
|
-------------- | ---------- | -------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
For the purpose of booting, there may be two EFI boot image files in the
|
||||||
|
ISO image. A VFAT image and a HFS+ image. The content of both is not in the
|
||||||
|
scope of this document.
|
||||||
|
These boot images get announced by EL Torito boot catalog entries with
|
||||||
|
Platform Id 0xef.
|
||||||
|
|
||||||
|
|
||||||
|
Newer SYSLINUX MBR templates begin by 32 bytes of machine code which are
|
||||||
|
intentionally non-essential:
|
||||||
|
33 ed 90 90 90 90 90 90 90 90 90 90 90 90 90 90
|
||||||
|
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
|
||||||
|
They may be overwritten by other bytes which must not produce errors or
|
||||||
|
undesirable side effects when executed as x86 machine code.
|
||||||
|
The following 32 bytes from block 0 of an Apple Partiton Map (APM) are such
|
||||||
|
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garret:
|
||||||
|
45 52 08 00 00 00 90 90 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
They do not depend on any properties of the ISO image or the information
|
||||||
|
that is described in the following text.
|
||||||
|
|
||||||
|
The layout of Block0 is constant:
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (all numbers are stored big endian)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 1 | sig | Signature 0x45 = 'E' , 0x52 = 'R'
|
||||||
|
2 - 3 | block_size | 0x0800 = 2048
|
||||||
|
4 - 7 | block_count| 0x9090 = 37008
|
||||||
|
8 - 9 | dev_type | obscure: "device type" = 0
|
||||||
|
10 - 11 | dev_id | obscure: "device id" = 0
|
||||||
|
12 - 15 | drv_data | obscure: "driver data" = 0
|
||||||
|
16 - 17 | drv_count | obscure: "driver descriptor count" = 0
|
||||||
|
18 - 81 | drv_map | obscure: "driver descriptor table"
|
||||||
|
| | with 8 entries of 16 bytes each
|
||||||
|
| | first 14 bytes are 0
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
The block_count of 0x9090 is pure fantasy. It shall only mark the disc as
|
||||||
|
not empty.
|
||||||
|
|
||||||
|
The data block ranges of the two EFI boot images get described by MBR
|
||||||
|
partition entries 2 and 3, which thus claim blocks inside of partition 1.
|
||||||
|
This partition nesting is acceptable to some EFI implementations only if the
|
||||||
|
type of partition 1 is 0x00.
|
||||||
|
|
||||||
|
The MBR partition entry number 1 is
|
||||||
|
80 00 01 00 00 3f a0 89 00 00 00 00 00 50 14 00
|
||||||
|
It marks the partition as bootable, starting at block 0, with a size that
|
||||||
|
is the smallest full MiB not smaller than the ISO image size + 18 KiB.
|
||||||
|
(The 18 KiB are needed for the GPT backup.)
|
||||||
|
The ISO image has a size of 332362 blocks of 2K = 1329448 * 512 = 649.14 MiB.
|
||||||
|
The partition size is 0x145000 = 1331200 * 512 = 650 MiB.
|
||||||
|
Start C/H/S = 0/0/1, type is 0x0 ("Empty"), end C/H/S is 649/63/32.
|
||||||
|
|
||||||
|
Partition 2:
|
||||||
|
00 fe ff ff ef fe ff ff a4 00 00 00 70 04 00 00
|
||||||
|
Start block is 0xa4 = 164 * 512 = 41 * 2048. The VFAT image file.
|
||||||
|
Partition size is 0x0470 = 1136 * 512. The size of that file.
|
||||||
|
Start C/H/S = 1023/254/63, type 0xef (fdisk says: "EFI (FAT-12/16/"),
|
||||||
|
end C/H/S = 1023/254/63.
|
||||||
|
|
||||||
|
Partition 3:
|
||||||
|
00 fe ff ff 00 fe ff ff 44 05 00 00 c0 08 00 00
|
||||||
|
Start block is 0x0544 = 1348 * 512 = 337 * 2048. The HFS+ image file.
|
||||||
|
Partition size is 0x08c0 = 2240 * 512. The size of that file.
|
||||||
|
Start C/H/S = 1023/254/63, type 0x00 ("Empty"), end C/H/S = 1023/254/63.
|
||||||
|
|
||||||
|
|
||||||
|
The second 512-block in the ISO image is the GPT header.
|
||||||
|
|
||||||
|
45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00
|
||||||
|
E F I P A R T
|
||||||
|
13 db 71 5d 00 00 00 00 01 00 00 00 00 00 00 00
|
||||||
|
fe 4f 14 00 00 00 00 00 30 00 00 00 00 00 00 00
|
||||||
|
de 4f 14 00 00 00 00 00 73 23 c8 79 19 e6 97 4d
|
||||||
|
95 17 69 30 c5 38 e2 99 10 00 00 00 00 00 00 00
|
||||||
|
80 00 00 00 80 00 00 00 5b 6b 8a 65
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
12 - 15 | head_size | Header size = 0x5c = 92
|
||||||
|
24 - 31 | curr_lba | Location of this header block = 0x1
|
||||||
|
32 - 39 | back_lba | Location of header backup block = 0x144ffe = 1331198
|
||||||
|
| | This is 1 KiB before the end of MBR partition 1
|
||||||
|
| | (but should be 512 bytes).
|
||||||
|
| | (Potential isohybrid.c bug #1:
|
||||||
|
| | Backup GPT is dislocated by 512 bytes.)
|
||||||
|
40 - 47 | first_lba | First usable LBA for partitions = 0x30 = 48
|
||||||
|
48 - 55 | last_lba | Last usable LBA for partitions = 0x144fde = 1331166
|
||||||
|
56 - 71 | guid | Disk GUID
|
||||||
|
| | Random, produced by uuid_generate(),
|
||||||
|
| | 32,16,16 byte swapped
|
||||||
|
72 - 79 | part_start | Partition entries start LBA = 0x10 = 16 = byte 0x2000
|
||||||
|
| | (This is unusual. It leaves room for the Apple
|
||||||
|
| | partition map entries.)
|
||||||
|
80 - 83 | entry_count| Number of partition entries 0x80 = 128
|
||||||
|
84 - 87 | entry_size | Size of a partition entry = 0x80 = 128
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Because the block size was announced as 2048, the first Apple partition map
|
||||||
|
entry is located at byte 0x800 = 2048.
|
||||||
|
It describes the partition map itself:
|
||||||
|
50 4d 00 00 00 00 00 03 00 00 00 01 00 00 00 10
|
||||||
|
P M
|
||||||
|
41 70 70 6c 65 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
A p p l e
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
41 70 70 6c 65 5f 70 61 72 74 69 74 69 6f 6e 5f
|
||||||
|
A p p l e _ p a r t i t i o n _
|
||||||
|
6d 61 70 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
m a p
|
||||||
|
00 00 00 00 00 00 00 0a 00 00 00 03 00 00 00 00
|
||||||
|
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (all numbers are stored big endian)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
4 - 7 | map_entries| "number of partition entries" = 3
|
||||||
|
8 - 11 | start_block| "physical block start of partition" = 1
|
||||||
|
12 - 15 | block_count| "physical block count of partition" = 16
|
||||||
|
| | (Potential isohybrid.c bug #2:
|
||||||
|
| | The value of 16 claims the ISO 9660 PVD as part of
|
||||||
|
| | the partition table. It should be 4 instead.)
|
||||||
|
16 - 47 | name | Partition name = "Apple"
|
||||||
|
48 - 79 | type | Type string = "Apple_partition_map"
|
||||||
|
80 - 83 | lb_start | Logical block start = 0
|
||||||
|
84 - 87 | lb_count | Logical block count = 10
|
||||||
|
88 - 91 | flags | Status flags = 3 (valid, allocated)
|
||||||
|
92 - 95 | boot_block | Logical start block number of boot code = 0
|
||||||
|
96 - 99 | boot_bytes | Number of bytes in boot code = 0
|
||||||
|
100 - 119 | | More boot code stuff = 0
|
||||||
|
120 - 135 | processor | "processor type" = 0
|
||||||
|
136 - 511 | reserved |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
(Potential isohybrid.c bug #2:
|
||||||
|
Apple partition map entries bear the block count for blocks of 512 bytes
|
||||||
|
whereas Apple Block0 announces blocks of 2048 bytes.)
|
||||||
|
|
||||||
|
The next Apple partition map entry is at byte 0x1000 = 4096:
|
||||||
|
|
||||||
|
50 4d 00 00 00 00 00 03 00 00 00 29 00 00 04 70
|
||||||
|
45 46 49 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
E F I
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
41 70 70 6c 65 5f 48 46 53 00 00 00 00 00 00 00
|
||||||
|
A p p l e _ H F S
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 04 70 00 00 00 33 00 00 00 00
|
||||||
|
|
||||||
|
3 partitions, start block is 0x29 = 41,
|
||||||
|
block count is 0x0470 = 1136 (should be 284), name is "EFI",
|
||||||
|
type is "Apple_HFS" (although this is a FAT image),
|
||||||
|
logical block start = 0, lb_count = 1136 (should be 284),
|
||||||
|
flags = 0x33 : valid, allocated, readable, writable.
|
||||||
|
This points to file /isolinux/efiboot.img in the ISO image.
|
||||||
|
(Potential isohybrid.c bug #2:
|
||||||
|
Apple partition map entries bear the block count for blocks of 512 bytes
|
||||||
|
whereas Apple Block0 announces blocks of 2048 bytes.)
|
||||||
|
|
||||||
|
At byte 0x1800 = 6144, there is Apple partition map entry 3:
|
||||||
|
|
||||||
|
50 4d 00 00 00 00 00 03 00 00 01 51 00 00 08 c0
|
||||||
|
45 46 49 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
E F I
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
41 70 70 6c 65 5f 48 46 53 00 00 00 00 00 00 00
|
||||||
|
A p p l e _ H F S
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 08 c0 00 00 00 33 00 00 00 00
|
||||||
|
|
||||||
|
3 partitions, start block is 0x0151 = 337 (LBA of /isolinux/macboot.img),
|
||||||
|
block count = 0x08c0 = 2240 (should be 560), name is "EFI",
|
||||||
|
type is "Apple_HFS", logical block start = 0, lb_count = 2240 (should be 560),
|
||||||
|
flags = 0x33 : valid, allocated, readable, writable.
|
||||||
|
(Potential isohybrid.c bug #2:
|
||||||
|
Apple partition map entries bear the block count for blocks of 512 bytes
|
||||||
|
whereas Apple Block0 announces blocks of 2048 bytes.)
|
||||||
|
|
||||||
|
At byte 0x2000 = 8192 begins the GPT partition array.
|
||||||
|
It ends at byte 0x4000 = 16384.
|
||||||
|
|
||||||
|
a2 a0 d0 eb e5 b9 33 44 87 c0 68 b6 b7 26 99 c7
|
||||||
|
a1 87 a1 ba 4d 2c 27 45 ae 05 cf ab a6 fa 87 c1
|
||||||
|
00 00 00 00 00 00 00 00 28 49 14 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
|
||||||
|
I S O H y b r i
|
||||||
|
64 20 49 53 4f 00 49 53 4f 48 79 62 72 69 64 00
|
||||||
|
d I S O I S O H y b r i d
|
||||||
|
41 70 70 6c 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
A p p l
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning (numbers are stored little endian)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 15 | type_guid | Partition type GUID = Basic data partition
|
||||||
|
| | Wikipedia: "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"
|
||||||
|
| | (Note: The first three words are shown byte swapped)
|
||||||
|
16 - 31 | part_guid | Unique partition GUID
|
||||||
|
| | Random, produced by uuid_generate()
|
||||||
|
| | 32,16,16 byte swapped
|
||||||
|
32 - 39 | start_lba | First LBA = 0
|
||||||
|
40 - 47 | end_lba | Last LBA (inclusive) = 0x144828 = 1329448
|
||||||
|
| | This is the ISO image size in blocks of 512.
|
||||||
|
| | (Potential isohybrid.c bug #3:
|
||||||
|
| | The end_lba in the first GPT entry should be 1 less
|
||||||
|
| | than the count of 512 byte blocks of the ISO image.)
|
||||||
|
48 - 55 | flags | Attribute flags = 0
|
||||||
|
56 - 127 | name | Wikipedia says UTF-16LE.
|
||||||
|
| | (Potential isohybrid.c bug #4:
|
||||||
|
| | The name in Fedora-LiveCD.iso is 8 bit and result
|
||||||
|
| | of faulty memory operation on a text constant.)
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
Next entry is at 0x2800 = 10240:
|
||||||
|
|
||||||
|
a2 a0 d0 eb e5 b9 33 44 87 c0 68 b6 b7 26 99 c7
|
||||||
|
c8 de c8 1f fb f0 51 40 8c 8a d2 f6 b1 46 16 dc
|
||||||
|
a4 00 00 00 00 00 00 00 13 05 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
|
||||||
|
I S O H y b r i
|
||||||
|
64 00 41 70 70 6c 65 00 41 70 70 6c 00 00 00 00
|
||||||
|
d A p p l e A p p l
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
Partition type GUID : "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" = Basic data
|
||||||
|
Start at block 0xa4 = 164 * 512 = 41 * 2048. The VFAT image file.
|
||||||
|
Last block is 0x0513 = 1299 = 164 + 1135. This end is correct.
|
||||||
|
(Potential isohybrid.c bug #4:
|
||||||
|
Wrong character set and incidential bytes in GPT partition name.)
|
||||||
|
|
||||||
|
Next entry at byte 0x02100 = 8448:
|
||||||
|
|
||||||
|
00 53 46 48 00 00 aa 11 aa 11 00 30 65 43 ec ac
|
||||||
|
c8 de c8 1f fb f0 51 40 8c 8a d2 f6 b1 46 16 dc
|
||||||
|
44 05 00 00 00 00 00 00 03 0e 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 49 53 4f 48 79 62 72 69
|
||||||
|
I S O H y b r i
|
||||||
|
64 00 41 70 70 6c 65 00 41 70 70 6c 00 00 00 00
|
||||||
|
d A p p l e A p p l
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
|
||||||
|
Partition type GUID : "48465300-0000-11AA-AA11-00306543ECAC" = HFS+
|
||||||
|
Start block is 0x0544 = 1348 * 512 = 337 * 2048. The HFS+ image file.
|
||||||
|
Last block is 0x0e03 = 3587 = 1348 + 2239. Correct.
|
||||||
|
(Potential isohybrid.c bug #4:
|
||||||
|
Wrong character set and incidential bytes in GPT partition name.)
|
||||||
|
|
||||||
|
The rest of the System Area is 0 up to the Primary Volume Descriptor
|
||||||
|
at block 16.
|
||||||
|
|
||||||
|
|
||||||
|
The ISO image file gets padded up to full MiB with sufficient room for the GPT
|
||||||
|
backup which is stored near the very end of the image file. There is need for
|
||||||
|
at least 16.5 KiB, which effectively occupy 18 KiB.
|
||||||
|
|
||||||
|
The backup partition array is stored 17 KiB before the end of MBR partition 1
|
||||||
|
resp. the image file.
|
||||||
|
(Potential isohybrid.c bug #1:
|
||||||
|
Wikipedia suggests "LBA -33" counted from end. This would be 16.5 KiB before
|
||||||
|
end.)
|
||||||
|
|
||||||
|
The GPT header is stored 1 KiB before the end of MBR partition 1.
|
||||||
|
(Potential isohybrid.c bug #1:
|
||||||
|
Wikipedia suggests "LBA -1" counted from end. This would be 512 bytes.)
|
||||||
|
|
||||||
|
45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00
|
||||||
|
E F I P A R T
|
||||||
|
f6 61 10 1c 00 00 00 00 fe 4f 14 00 00 00 00 00
|
||||||
|
01 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00
|
||||||
|
de 4f 14 00 00 00 00 00 73 23 c8 79 19 e6 97 4d
|
||||||
|
95 17 69 30 c5 38 e2 99 de 4f 14 00 00 00 00 00
|
||||||
|
80 00 00 00 80 00 00 00 5b 6b 8a 65
|
||||||
|
|
||||||
|
It differs by its own CRC and by some of its parameters:
|
||||||
|
Own address is 0x144ffe. The backup lba is 0x01 = Primary GPT header.
|
||||||
|
Partition entries start is 0x144fde
|
||||||
|
(Potential isohybrid.c bug #1:
|
||||||
|
This overlaps with the last usable LBA. The backup GPT must move up by
|
||||||
|
512 bytes.)
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
GRUB2 grub-mkrescue MBR
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
Mailing list conversations with Vladimir Serbinenko.
|
||||||
|
|
||||||
|
|
||||||
|
The MBR file that is used with older versions of GRUB2 script grub-mkrescue
|
||||||
|
needs only a partition table entry which describes the image size.
|
||||||
|
Newer versions get patched by the block address of the content of the first
|
||||||
|
El Torito boot image. See grub-mkrescue use of xorrisofs option --grub2-mbr.
|
||||||
|
|
||||||
|
Byte Range | Value | Meaning
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
0 - 431 | = opaque = | GRUB2 machine code provided by MBR template
|
||||||
|
| |
|
||||||
|
432 - 439 | bootimg_adr| With newer versions of grub-mkrescue:
|
||||||
|
| | Block address of the start of the boot image file
|
||||||
|
| | content plus 4. Block size is 512.
|
||||||
|
| | 64 bit Little-endian.
|
||||||
|
| |
|
||||||
|
440 - 445 | = opaque = | provided by MBR template
|
||||||
|
| |
|
||||||
|
446 - 509 | ========== | Partition table
|
||||||
|
| |
|
||||||
|
446 - 461 | part_entry | Partition table entry 1 describing ISO image size
|
||||||
|
| | Peculiar is the start offset of 1 block.
|
||||||
|
| | This prevents mounting of the partition.
|
||||||
|
| | See above for partition table entry format.
|
||||||
|
| |
|
||||||
|
462 - 509 | 0 | Unused partition entries 2 to 4
|
||||||
|
510 - 511 | 0xaa55 | MBR signature
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
Vladimir Serbinenko about the partition table entry:
|
||||||
|
"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
|
||||||
|
"
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
>>> Mac and/or PowerPC bootable GRUB2 image with HFS+/FAT, APM,
|
||||||
|
EFI GPT partition, PreP MBR partition, mountable FAT partition
|
||||||
|
|
||||||
|
>>> ? With PC-BIOS MBR x86 Code ?
|
||||||
|
|
||||||
|
This storage layout was mainly defined by Vladimir Serbinenko. It relies much
|
||||||
|
on the embedded HFS+/FAT filesystem for which he provided the code to libisofs.
|
||||||
|
|
||||||
|
Start Blocks (2 KiB):
|
||||||
|
0 System Area
|
||||||
|
16 Volume Descriptors
|
||||||
|
TREE ISO-RR tree, Joliet tree, other trees and meta data, except HFS+/FAT
|
||||||
|
EFI EFI boot image partition (optional)
|
||||||
|
PREP Prep image partition (optional)
|
||||||
|
HFAT HFS+/FAT metadata (optional)
|
||||||
|
DATA Data file content (including El Torito boot images)
|
||||||
|
HFSB HFS superblock backup (if HFS+/FAT metadata)
|
||||||
|
TAIL Further tails and paddings (optional)
|
||||||
|
GPTB GPT backup (if GPT in System Area)
|
||||||
|
END End of ISO image
|
||||||
|
|
||||||
|
System Area may contain simultaneously:
|
||||||
|
MBR (x86 boot code must leave room for 8 bytes mock-up of APM Block0)
|
||||||
|
APM
|
||||||
|
GPT
|
||||||
|
|
||||||
|
MBR Partitions:
|
||||||
|
0xee from 0 to PREP-1, protective partition, announcing presence of GPT
|
||||||
|
0x41 from PREP to HFAT-1, PreP partition
|
||||||
|
0x0c from HFAT to END-1, FAT partition, bootable bit on
|
||||||
|
0x00 Empty partition
|
||||||
|
|
||||||
|
GPT Partitions:
|
||||||
|
The primary GPT itself covers the System Area.
|
||||||
|
Basic Data from 16 to EFI-1, protects first part of ISO image
|
||||||
|
EFI System from EFI to PREP-1, offers EFI image for booting
|
||||||
|
Basic Data from PREP to HFAT-1, protects PreP partition
|
||||||
|
HFS+ from HFAT to TAIL-1, offers HFS+ for mounting
|
||||||
|
Basic Data from TAIL to GPTB-1, protects rest of ISO image (if there is)
|
||||||
|
|
||||||
|
APM Partitions:
|
||||||
|
The range from end of APM to end of System Area stays unprotected.
|
||||||
|
(The primary GPT might sit there.)
|
||||||
|
Apple_partition_map from 1 to 3 or 4, covers the APM itself
|
||||||
|
ISO9660_data from 16 to HFAT-1, covers first part of ISO image
|
||||||
|
Apple_HFS from HFAT to GPTB-1, offers HFS+ for boot and mount
|
||||||
|
ISO9660_data from GPTB to END-1, covers rest of ISO image
|
||||||
|
(might be omitted if empty)
|
||||||
|
|
||||||
|
El Torito:
|
||||||
|
Boot image for 80x86 PC-BIOS
|
||||||
|
Boot image for EFI (usually the same file as the partition EFI to PREP-1).
|
||||||
|
|
||||||
|
If optional components are not present, then their addresses coincide with
|
||||||
|
the address of the next component that is present. E.g. HFAT == DATA if no
|
||||||
|
HFS+/FAT filesystem is present.
|
||||||
|
If no FAT filesystem is present within HFS+/FAT, then the type of the last
|
||||||
|
partition is 0xcd.
|
||||||
|
If neither EFI, nor PreP, nor FAT within HFS+/FAT, are present, then there
|
||||||
|
is only one partition. It has type 0xee, if GPT is present in the System Area.
|
||||||
|
It has type 0xcd and offset 1*512, if no GPT is present.
|
||||||
|
|
||||||
|
Involved -as mkisofs options:
|
||||||
|
-hfsplus
|
||||||
|
-fat
|
||||||
|
-efi-boot-part DISKFILE
|
||||||
|
-prep-boot-part DISKFILE
|
||||||
|
|
||||||
|
|
||||||
|
>>> What boots by what ?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||||
Libburnia project - mailto:libburn-hackers@pykix.org
|
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||||
21 Feb 2012
|
07 Jun 2012
|
||||||
|
|
||||||
|
|
||||||
The overall framework for the filesystem images produced by libisofs is given
|
The overall framework for the filesystem images produced by libisofs is given
|
||||||
@ -84,6 +84,23 @@ libisofs/ecma119.h at struct ecma119_image.system_area_options and in
|
|||||||
libisofs/libisofs.h at call iso_write_opts_set_system_area(). See e.g.
|
libisofs/libisofs.h at call iso_write_opts_set_system_area(). See e.g.
|
||||||
"MIPS Big Endian Volume Header".
|
"MIPS Big Endian Volume Header".
|
||||||
|
|
||||||
|
libisofs/system_area.h offers an inner API to define partitions for Apple
|
||||||
|
Partition Map (APM) and for GPT from within the compute_data_blocks methods
|
||||||
|
of the IsoImageWriter objects (see below). If both get combined, then
|
||||||
|
APM block size must be 2048. In this case, the partition entries of APM
|
||||||
|
and GPT overwrite the following bytes of the submitted
|
||||||
|
Ecma119Image.system_area_data:
|
||||||
|
0x0000 to 0x0007 by { 0x45, 0x52, 0x08 0x00, 0xeb, 0x02, 0xff, 0xff}
|
||||||
|
0x0200 to 0x02ff by GPT header block
|
||||||
|
0x0800 to APM_end by APM blocks (APM_end = 2048*(Num_APM_partitions + 1)
|
||||||
|
APM_end+1 to 0x7fff by GPT entries
|
||||||
|
This offers still room for a PC-BIOS MBR which has essentially no-op commands
|
||||||
|
in its first 8 bytes.
|
||||||
|
If no GPT is desired, then the bytes after APM_end stay unaltered.
|
||||||
|
If more modesty with overwriting is needed, then this would have to be caused
|
||||||
|
by either a specialized system area type or by additional elements of the
|
||||||
|
inner API for APM and GPT.
|
||||||
|
|
||||||
|
|
||||||
The layout of the areas above image_start+16 is defined in function
|
The layout of the areas above image_start+16 is defined in function
|
||||||
libisofs/ecma119.c:ecma119_image_new(). This is done by creating and
|
libisofs/ecma119.c:ecma119_image_new(). This is done by creating and
|
||||||
@ -120,6 +137,8 @@ libisofs will call the methods of the writer object when it computes the
|
|||||||
block addresses of the various image components, when it writes volume
|
block addresses of the various image components, when it writes volume
|
||||||
descriptors, when it writes directory trees, and when it finally disposes the
|
descriptors, when it writes directory trees, and when it finally disposes the
|
||||||
Ecma119Image object.
|
Ecma119Image object.
|
||||||
|
Before calling the first method, it will publish the number of data file
|
||||||
|
content blocks in Ecma119Image.filesrc_blocks.
|
||||||
|
|
||||||
The method IsoImageWriter.compute_data_blocks() has to predict the storage
|
The method IsoImageWriter.compute_data_blocks() has to predict the storage
|
||||||
needs in the area of directory trees.
|
needs in the area of directory trees.
|
||||||
@ -148,6 +167,15 @@ struct iso_file_section is defined in libisofs/libisofs.h.
|
|||||||
IsoImageWriter.free_data() disposes the writer and the JolietNode tree.
|
IsoImageWriter.free_data() disposes the writer and the JolietNode tree.
|
||||||
|
|
||||||
|
|
||||||
|
Further examples for add-on writers are those created by:
|
||||||
|
|
||||||
|
hfsplus_writer_create() is in charge for initial part of an
|
||||||
|
embedded HFS+ filesystem
|
||||||
|
hfsplus_tail_writer_create() is in charge for trailing part of HFS+
|
||||||
|
after the data file content area
|
||||||
|
gpt_tail_writer_create() is in charge for the backup GPT near the
|
||||||
|
end of the ISO image
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
This text is under
|
This text is under
|
||||||
|
@ -109,8 +109,6 @@ Each Component Record shall have the following format:
|
|||||||
[B] "BP 2 - Component Length (LEN_CP)" shall specify as an 8-bit number the
|
[B] "BP 2 - Component Length (LEN_CP)" shall specify as an 8-bit number the
|
||||||
number of component bytes in the Component Record. This length shall not
|
number of component bytes in the Component Record. This length shall not
|
||||||
include the first two bytes of the Component Record.
|
include the first two bytes of the Component Record.
|
||||||
If any of the bit positions 1-3 is set, the value of this field shall be
|
|
||||||
set to ZERO and no Component Content shall be recorded.
|
|
||||||
This field shall be recorded according to ISO 9660 Format section 7.1.1.
|
This field shall be recorded according to ISO 9660 Format section 7.1.1.
|
||||||
|
|
||||||
[C] "BP 3 to 2 + LEN_CP - Component Content" shall contain the component
|
[C] "BP 3 to 2 + LEN_CP - Component Content" shall contain the component
|
||||||
@ -445,7 +443,7 @@ Program mkisofs emits entry XA
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
This text is under
|
This text is under
|
||||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
It shall only be modified in sync with libisofs and other software which
|
It shall only be modified in sync with libisofs and other software which
|
||||||
makes use of AAIP. Please mail change requests to mailing list
|
makes use of AAIP. Please mail change requests to mailing list
|
||||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||||
|
@ -123,6 +123,55 @@ Registered:
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Name:
|
||||||
|
isofs.hb
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Records the IsoHfsplusBlessings blessing of a IsoNode as defined
|
||||||
|
in libisofs.h. At image load time, this info shall be converted back
|
||||||
|
into a relation between IsoImage and IsoNode so that it is available for
|
||||||
|
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
||||||
|
|
||||||
|
Format of Value:
|
||||||
|
BLESSING
|
||||||
|
This is a single byte out of {'p', 'i', 's', '9', 'x'} for
|
||||||
|
ISO_HFSPLUS_BLESS_PPC_BOOTDIR, ISO_HFSPLUS_BLESS_INTEL_BOOTFILE,
|
||||||
|
ISO_HFSPLUS_BLESS_SHOWFOLDER, ISO_HFSPLUS_BLESS_OS9_FOLDER,
|
||||||
|
ISO_HFSPLUS_BLESS_OSX_FOLDER.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{ 'p' }
|
||||||
|
|
||||||
|
Registered:
|
||||||
|
07 Jun 2012 by Thomas Schmitt for xorriso.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Name:
|
||||||
|
isofs.hx
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Records the iso_hfsplus_xinfo_data information as defined in libisofs.h.
|
||||||
|
At image load time, this info shall be converted back into an xinfo
|
||||||
|
attachment for iso_hfsplus_xinfo_func so that it is available for
|
||||||
|
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
||||||
|
|
||||||
|
Format of Value:
|
||||||
|
VERSION_LEN | VERSION | CREATOR | TYPE
|
||||||
|
VERSION_LEN complies to ISO 9660 Format section 7.1.1.
|
||||||
|
The byte string VERSION begins with the most significant byte.
|
||||||
|
VERSION == 0 is the only one that is currently defined. It assures the
|
||||||
|
existence of 4 bytes CREATOR and 4 bytes TYPE.
|
||||||
|
Higher versions will keep these 8 bytes and possibly add new ones.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{ 1, 0, 'Y', 'Y', 'D', 'N', 'T', 'E', 'X', 'T' }
|
||||||
|
|
||||||
|
Registered:
|
||||||
|
07 Jun 2012 by Thomas Schmitt for xorriso.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Name:
|
Name:
|
||||||
isofs.st
|
isofs.st
|
||||||
|
|
||||||
|
@ -2065,7 +2065,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
unsigned char *rpt;
|
unsigned char *rpt;
|
||||||
char perm_text[4], *wpt, *name= NULL;
|
char perm_text[4], *wpt, *name= NULL;
|
||||||
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
|
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
|
||||||
size_t w_size, name_fill= 0, i;
|
size_t w_size= 0, name_fill= 0, i;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
#include "joliet.h"
|
#include "joliet.h"
|
||||||
|
#include "hfsplus.h"
|
||||||
#include "iso1999.h"
|
#include "iso1999.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "ecma119_tree.h"
|
#include "ecma119_tree.h"
|
||||||
@ -89,14 +90,8 @@ void ecma119_image_free(Ecma119Image *t)
|
|||||||
writer->free_data(writer);
|
writer->free_data(writer);
|
||||||
free(writer);
|
free(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
if (t->rr_reloc_dir != NULL)
|
if (t->rr_reloc_dir != NULL)
|
||||||
free(t->rr_reloc_dir);
|
free(t->rr_reloc_dir);
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
if (t->input_charset != NULL)
|
if (t->input_charset != NULL)
|
||||||
free(t->input_charset);
|
free(t->input_charset);
|
||||||
if (t->output_charset != NULL)
|
if (t->output_charset != NULL)
|
||||||
@ -115,9 +110,25 @@ void ecma119_image_free(Ecma119Image *t)
|
|||||||
free(t->writers);
|
free(t->writers);
|
||||||
if (t->partition_root != NULL)
|
if (t->partition_root != NULL)
|
||||||
ecma119_node_free(t->partition_root);
|
ecma119_node_free(t->partition_root);
|
||||||
|
if (t->prep_partition != NULL)
|
||||||
|
free(t->prep_partition);
|
||||||
|
if (t->efi_boot_partition != NULL)
|
||||||
|
free(t->efi_boot_partition);
|
||||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||||
if (t->appended_partitions[i] != NULL)
|
if (t->appended_partitions[i] != NULL)
|
||||||
free(t->appended_partitions[i]);
|
free(t->appended_partitions[i]);
|
||||||
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||||
|
if (t->hfsplus_blessed[i] != NULL)
|
||||||
|
iso_node_unref(t->hfsplus_blessed[i]);
|
||||||
|
for (i = 0; (int) i < t->apm_req_count; i++)
|
||||||
|
if (t->apm_req[i] != NULL)
|
||||||
|
free(t->apm_req[i]);
|
||||||
|
for (i = 0; (int) i < t->mbr_req_count; i++)
|
||||||
|
if (t->mbr_req[i] != NULL)
|
||||||
|
free(t->mbr_req[i]);
|
||||||
|
for (i = 0; (int) i < t->gpt_req_count; i++)
|
||||||
|
if (t->gpt_req[i] != NULL)
|
||||||
|
free(t->gpt_req[i]);
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
@ -451,6 +462,64 @@ char *get_relaxed_vol_id(Ecma119Image *t, const char *name)
|
|||||||
return strdup(name);
|
return strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the timestamps of Primary, Supplementary, or Enhanced Volume Descriptor.
|
||||||
|
*/
|
||||||
|
void ecma119_set_voldescr_times(IsoImageWriter *writer,
|
||||||
|
struct ecma119_pri_vol_desc *vol)
|
||||||
|
{
|
||||||
|
Ecma119Image *t = writer->target;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
vol->vol_expiration_time[i] = '0';
|
||||||
|
vol->vol_expiration_time[16] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->vol_effective_time > 0) {
|
||||||
|
iso_datetime_17(vol->vol_effective_time, t->vol_effective_time,
|
||||||
|
t->always_gmt);
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
vol->vol_effective_time[i] = '0';
|
||||||
|
vol->vol_effective_time[16] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the Primary Volume Descriptor (ECMA-119, 8.4)
|
* Write the Primary Volume Descriptor (ECMA-119, 8.4)
|
||||||
*/
|
*/
|
||||||
@ -460,7 +529,6 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
IsoImage *image;
|
IsoImage *image;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
struct ecma119_pri_vol_desc vol;
|
struct ecma119_pri_vol_desc vol;
|
||||||
int i;
|
|
||||||
char *vol_id, *pub_id, *data_id, *volset_id;
|
char *vol_id, *pub_id, *data_id, *volset_id;
|
||||||
char *system_id, *application_id, *copyright_file_id;
|
char *system_id, *application_id, *copyright_file_id;
|
||||||
char *abstract_file_id, *biblio_file_id;
|
char *abstract_file_id, *biblio_file_id;
|
||||||
@ -526,46 +594,11 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
|
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
|
||||||
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
|
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
|
||||||
|
|
||||||
if (t->vol_uuid[0]) {
|
ecma119_set_voldescr_times(writer, &vol);
|
||||||
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;
|
vol.file_structure_version[0] = 1;
|
||||||
|
|
||||||
|
memcpy(vol.app_use, image->application_use, 512);
|
||||||
|
|
||||||
free(vol_id);
|
free(vol_id);
|
||||||
free(volset_id);
|
free(volset_id);
|
||||||
free(pub_id);
|
free(pub_id);
|
||||||
@ -959,6 +992,14 @@ int ecma119_writer_create(Ecma119Image *target)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target->image->sparc_core_node != NULL) {
|
||||||
|
/* Obtain a duplicate of the IsoFile's Ecma119Node->file */
|
||||||
|
ret = iso_file_src_create(target, target->image->sparc_core_node,
|
||||||
|
&target->sparc_core_src);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if(target->partition_offset > 0) {
|
if(target->partition_offset > 0) {
|
||||||
/* Create second tree */
|
/* Create second tree */
|
||||||
target->eff_partition_offset = target->partition_offset;
|
target->eff_partition_offset = target->partition_offset;
|
||||||
@ -1189,6 +1230,48 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= restore preserved cx (else dispose them)
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int process_preserved_cx(IsoDir *dir, int flag)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
unsigned int cx_value;
|
||||||
|
void *xipt;
|
||||||
|
IsoNode *pos;
|
||||||
|
|
||||||
|
pos = dir->children;
|
||||||
|
for (pos = dir->children; pos != NULL; pos = pos->next) {
|
||||||
|
if (pos->type == LIBISO_FILE) {
|
||||||
|
if (flag & 1) {
|
||||||
|
/* Restore preserved cx state of nodes */
|
||||||
|
ret = iso_node_get_xinfo(pos, checksum_cx_xinfo_func,
|
||||||
|
&xipt);
|
||||||
|
if (ret == 1) {
|
||||||
|
/* xipt is an int disguised as void pointer */
|
||||||
|
cx_value = 0;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
cx_value =
|
||||||
|
(cx_value << 8) | ((unsigned char *) &xipt)[i];
|
||||||
|
ret = iso_file_set_isofscx((IsoFile *) pos, cx_value, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
/* Node had no cx before the write run. Delete cx. */
|
||||||
|
iso_file_set_isofscx((IsoFile *) pos, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iso_node_remove_xinfo(pos, checksum_cx_xinfo_func);
|
||||||
|
} else if (pos->type == LIBISO_DIR) {
|
||||||
|
ret = process_preserved_cx((IsoDir *) pos, flag);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
||||||
{
|
{
|
||||||
@ -1199,6 +1282,10 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
|||||||
target->checksum_idx_counter + 2, 0);
|
target->checksum_idx_counter + 2, 0);
|
||||||
target->checksum_buffer = NULL;
|
target->checksum_buffer = NULL;
|
||||||
target->checksum_idx_counter = 0;
|
target->checksum_idx_counter = 0;
|
||||||
|
|
||||||
|
/* Delete recorded cx xinfo */
|
||||||
|
process_preserved_cx(target->image->root, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,10 +1318,11 @@ static
|
|||||||
int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
||||||
{
|
{
|
||||||
int res, i;
|
int res, i;
|
||||||
uint8_t sa[16 * BLOCK_SIZE];
|
uint8_t *sa;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
size_t buffer_size = 0, buffer_free = 0, buffer_start_free = 0;
|
size_t buffer_size = 0, buffer_free = 0, buffer_start_free = 0;
|
||||||
|
|
||||||
|
sa = target->sys_area_as_written;
|
||||||
iso_ring_buffer_get_buf_status(target->buffer, &buffer_size,
|
iso_ring_buffer_get_buf_status(target->buffer, &buffer_size,
|
||||||
&buffer_start_free);
|
&buffer_start_free);
|
||||||
*write_count = 0;
|
*write_count = 0;
|
||||||
@ -1326,6 +1414,8 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
|||||||
|
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
|
if (buf != NULL)
|
||||||
|
free(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1377,8 +1467,8 @@ static int finish_libjte(Ecma119Image *target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||||
uint32_t prepad, uint32_t blocks, int flag)
|
uint32_t prepad, uint32_t blocks, int flag)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@ -1460,7 +1550,7 @@ void *write_function(void *arg)
|
|||||||
continue;
|
continue;
|
||||||
if (target->appended_partitions[i][0] == 0)
|
if (target->appended_partitions[i][0] == 0)
|
||||||
continue;
|
continue;
|
||||||
res = write_mbr_partition_file(target, target->appended_partitions[i],
|
res = iso_write_partition_file(target, target->appended_partitions[i],
|
||||||
target->appended_part_prepad[i],
|
target->appended_part_prepad[i],
|
||||||
target->appended_part_size[i], 0);
|
target->appended_part_size[i], 0);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -1484,7 +1574,15 @@ void *write_function(void *arg)
|
|||||||
|
|
||||||
if (target->tree_end_block == 1) {
|
if (target->tree_end_block == 1) {
|
||||||
iso_msgs_submit(0,
|
iso_msgs_submit(0,
|
||||||
"Image is most likely damaged. Calculated/written block address mismatch.",
|
"Image is most likely damaged. Calculated/written tree end address mismatch.",
|
||||||
|
0, "FATAL", 0);
|
||||||
|
}
|
||||||
|
if (target->bytes_written != target->total_size) {
|
||||||
|
iso_msg_debug(target->image->id,
|
||||||
|
"bytes_written = %.f <-> total_size = %.f",
|
||||||
|
(double) target->bytes_written, (double) target->total_size);
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"Image is most likely damaged. Calculated/written image end address mismatch.",
|
||||||
0, "FATAL", 0);
|
0, "FATAL", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1494,7 +1592,7 @@ void *write_function(void *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
write_error: ;
|
write_error: ;
|
||||||
if (res != (int) ISO_LIBJTE_END_FAILED)
|
if (res != (int) ISO_LIBJTE_END_FAILED)
|
||||||
finish_libjte(target);
|
finish_libjte(target);
|
||||||
target->eff_partition_offset = 0;
|
target->eff_partition_offset = 0;
|
||||||
@ -1510,11 +1608,9 @@ void *write_function(void *arg)
|
|||||||
}
|
}
|
||||||
iso_ring_buffer_writer_close(target->buffer, 1);
|
iso_ring_buffer_writer_close(target->buffer, 1);
|
||||||
|
|
||||||
/* Transplant checksum buffer away from Ecma119Image */
|
/* Re-activate recorded cx xinfo */
|
||||||
transplant_checksum_buffer(target, 0);
|
process_preserved_cx(target->image->root, 1);
|
||||||
/* Invalidate the transplanted checksum buffer in IsoImage */
|
|
||||||
iso_image_free_checksums(target->image, 0);
|
|
||||||
|
|
||||||
target->image->generator_is_running = 0;
|
target->image->generator_is_running = 0;
|
||||||
|
|
||||||
/* Give up reference claim made in ecma119_image_new().
|
/* Give up reference claim made in ecma119_image_new().
|
||||||
@ -1553,89 +1649,96 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
IsoNode *pos;
|
IsoNode *pos;
|
||||||
IsoFile *file;
|
IsoFile *file;
|
||||||
IsoImage *img;
|
IsoImage *img;
|
||||||
int ret, i, no_md5 = 0, has_xinfo = 0;
|
int ret, i, no_md5 = 0, has_xinfo = 0, has_attr = 0;
|
||||||
size_t value_length;
|
size_t old_cx_value_length = 0;
|
||||||
unsigned int idx = 0;
|
unsigned int idx = 0;
|
||||||
char *value= NULL;
|
char *old_cx_value= NULL;
|
||||||
void *xipt = NULL;
|
void *xipt = NULL;
|
||||||
static char *cx_names = "isofs.cx";
|
|
||||||
static size_t cx_value_lengths[1] = {0};
|
|
||||||
char *cx_valuept = "";
|
|
||||||
|
|
||||||
img= target->image;
|
img= target->image;
|
||||||
|
|
||||||
if (node->type == LIBISO_FILE) {
|
if (node->type == LIBISO_FILE) {
|
||||||
file = (IsoFile *) node;
|
file = (IsoFile *) node;
|
||||||
|
if (file->from_old_session) {
|
||||||
|
/* Record attribute isofs.cx as xinfo before it can get overwritten
|
||||||
|
for the emerging image.
|
||||||
|
The recorded index will be used to retrieve the loaded MD5
|
||||||
|
and it will be brought back into effect if cancellation of
|
||||||
|
image production prevents that the old MD5 array gets replaced
|
||||||
|
by the new one.
|
||||||
|
*/
|
||||||
|
has_attr = iso_node_lookup_attr(node, "isofs.cx",
|
||||||
|
&old_cx_value_length, &old_cx_value, 0);
|
||||||
|
if (has_attr == 1 && old_cx_value_length == 4) {
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
idx = (idx << 8) | ((unsigned char *) old_cx_value)[i];
|
||||||
|
if (idx > 0 && idx < 0x8000000) {
|
||||||
|
/* xipt is an int disguised as void pointer */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
((char *) &xipt)[i] = old_cx_value[i];
|
||||||
|
ret = iso_node_add_xinfo(node, checksum_cx_xinfo_func,
|
||||||
|
xipt);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
} else
|
||||||
|
no_md5 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (file->from_old_session && target->appendable) {
|
if (file->from_old_session && target->appendable) {
|
||||||
/* Save MD5 data of files from old image which will not
|
/* Save MD5 data of files from old image which will not
|
||||||
be copied and have an MD5 recorded in the old image. */
|
be copied and have an MD5 recorded in the old image. */
|
||||||
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
|
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
|
||||||
&xipt);
|
&xipt);
|
||||||
if (has_xinfo <= 0) {
|
|
||||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
|
||||||
&value, 0);
|
|
||||||
}
|
|
||||||
if (has_xinfo > 0) {
|
if (has_xinfo > 0) {
|
||||||
/* xinfo MD5 overrides everything else unless data get copied
|
/* xinfo MD5 overrides everything else unless data get copied
|
||||||
and checksummed during that copying
|
and checksummed during that copying
|
||||||
*/;
|
*/;
|
||||||
} else if (ret == 1 && img->checksum_array == NULL) {
|
} else if (has_attr == 1 && img->checksum_array == NULL) {
|
||||||
/* No checksum array loaded. Delete "isofs.cx" */
|
/* No checksum array loaded. Delete "isofs.cx" */
|
||||||
iso_node_set_attrs(node, (size_t) 1,
|
if (!target->will_cancel)
|
||||||
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
|
iso_file_set_isofscx((IsoFile *) node, 0, 1);
|
||||||
no_md5 = 1;
|
no_md5 = 1;
|
||||||
} else if (ret == 1 && value_length == 4) {
|
} else if (!(has_attr == 1 && old_cx_value_length == 4)) {
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
|
||||||
if (idx > 0 && idx < 0x8000000) {
|
|
||||||
/* xipt is an int disguised as void pointer */
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
((char *) &xipt)[i] = value[i];
|
|
||||||
ret = iso_node_add_xinfo(node, checksum_cx_xinfo_func,
|
|
||||||
xipt);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
} else
|
|
||||||
no_md5 = 1;
|
|
||||||
} else {
|
|
||||||
no_md5 = 1;
|
no_md5 = 1;
|
||||||
}
|
}
|
||||||
if (value != NULL) {
|
|
||||||
free(value);
|
|
||||||
value= NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
|
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
|
||||||
Omit those from old image which will not be copied and have no MD5.
|
Omit those from old image which will not be copied and have no MD5.
|
||||||
|
Do not alter the nodes if this is only a will_cancel run.
|
||||||
*/
|
*/
|
||||||
if (!no_md5) {
|
if (!(target->will_cancel || no_md5)) {
|
||||||
|
/* Record provisory new index */
|
||||||
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
} else if (node->type == LIBISO_DIR) {
|
} else if (node->type == LIBISO_DIR) {
|
||||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||||
ret = checksum_prepare_nodes(target, pos, 1);
|
ret = checksum_prepare_nodes(target, pos, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (old_cx_value != NULL)
|
||||||
|
free(old_cx_value);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||||
{
|
{
|
||||||
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
|
int ret, i, voldesc_size, nwriters, tag_pos;
|
||||||
int sa_type;
|
int sa_type;
|
||||||
Ecma119Image *target;
|
Ecma119Image *target;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
int el_torito_writer_index = -1, file_src_writer_index = -1;
|
int file_src_writer_index = -1;
|
||||||
int system_area_options = 0;
|
int system_area_options = 0;
|
||||||
char *system_area = NULL;
|
char *system_area = NULL;
|
||||||
int write_count = 0, write_count_mem;
|
int write_count = 0, write_count_mem;
|
||||||
|
|
||||||
|
|
||||||
/* 1. Allocate target and copy opts there */
|
/* 1. Allocate target and copy opts there */
|
||||||
target = calloc(1, sizeof(Ecma119Image));
|
target = calloc(1, sizeof(Ecma119Image));
|
||||||
if (target == NULL) {
|
if (target == NULL) {
|
||||||
@ -1659,6 +1762,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->iso_level = opts->level;
|
target->iso_level = opts->level;
|
||||||
target->rockridge = opts->rockridge;
|
target->rockridge = opts->rockridge;
|
||||||
target->joliet = opts->joliet;
|
target->joliet = opts->joliet;
|
||||||
|
target->hfsplus = opts->hfsplus;
|
||||||
|
target->fat = opts->fat;
|
||||||
target->iso1999 = opts->iso1999;
|
target->iso1999 = opts->iso1999;
|
||||||
target->hardlinks = opts->hardlinks;
|
target->hardlinks = opts->hardlinks;
|
||||||
target->aaip = opts->aaip;
|
target->aaip = opts->aaip;
|
||||||
@ -1682,9 +1787,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
||||||
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
||||||
target->dir_rec_mtime = opts->dir_rec_mtime;
|
target->dir_rec_mtime = opts->dir_rec_mtime;
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
target->rr_reloc_dir = NULL;
|
target->rr_reloc_dir = NULL;
|
||||||
if (opts->rr_reloc_dir != NULL) {
|
if (opts->rr_reloc_dir != NULL) {
|
||||||
target->rr_reloc_dir = strdup(opts->rr_reloc_dir);
|
target->rr_reloc_dir = strdup(opts->rr_reloc_dir);
|
||||||
@ -1695,9 +1797,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
}
|
}
|
||||||
target->rr_reloc_flags = opts->rr_reloc_flags;
|
target->rr_reloc_flags = opts->rr_reloc_flags;
|
||||||
target->rr_reloc_node = NULL;
|
target->rr_reloc_node = NULL;
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
target->sort_files = opts->sort_files;
|
target->sort_files = opts->sort_files;
|
||||||
|
|
||||||
target->replace_uid = opts->replace_uid ? 1 : 0;
|
target->replace_uid = opts->replace_uid ? 1 : 0;
|
||||||
@ -1750,6 +1849,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||||
if (opts->appended_partitions[i] != NULL)
|
if (opts->appended_partitions[i] != NULL)
|
||||||
return ISO_NON_MBR_SYS_AREA;
|
return ISO_NON_MBR_SYS_AREA;
|
||||||
|
if (sa_type != 0 && opts->prep_partition != NULL)
|
||||||
|
return ISO_NON_MBR_SYS_AREA;
|
||||||
|
|
||||||
target->system_area_data = NULL;
|
target->system_area_data = NULL;
|
||||||
if (system_area != NULL) {
|
if (system_area != NULL) {
|
||||||
@ -1798,6 +1899,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(target->hfsp_serial_number, opts->hfsp_serial_number, 8);
|
||||||
|
|
||||||
target->md5_file_checksums = opts->md5_file_checksums;
|
target->md5_file_checksums = opts->md5_file_checksums;
|
||||||
target->md5_session_checksum = opts->md5_session_checksum;
|
target->md5_session_checksum = opts->md5_session_checksum;
|
||||||
strcpy(target->scdbackup_tag_parm, opts->scdbackup_tag_parm);
|
strcpy(target->scdbackup_tag_parm, opts->scdbackup_tag_parm);
|
||||||
@ -1839,11 +1942,28 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->mipsel_p_vaddr = 0;
|
target->mipsel_p_vaddr = 0;
|
||||||
target->mipsel_p_filesz = 0;
|
target->mipsel_p_filesz = 0;
|
||||||
|
|
||||||
|
target->sparc_core_src = NULL;
|
||||||
|
|
||||||
target->empty_file_block = 0;
|
target->empty_file_block = 0;
|
||||||
target->tree_end_block = 0;
|
target->tree_end_block = 0;
|
||||||
|
|
||||||
target->wthread_is_running = 0;
|
target->wthread_is_running = 0;
|
||||||
|
|
||||||
|
target->prep_partition = NULL;
|
||||||
|
if (opts->prep_partition != NULL) {
|
||||||
|
target->prep_partition = strdup(opts->prep_partition);
|
||||||
|
if (target->prep_partition == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
target->prep_part_size = 0;
|
||||||
|
target->efi_boot_partition = NULL;
|
||||||
|
if (opts->efi_boot_partition != NULL) {
|
||||||
|
target->efi_boot_partition = strdup(opts->efi_boot_partition);
|
||||||
|
if (target->efi_boot_partition == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
target->efi_boot_part_size = 0;
|
||||||
|
target->efi_boot_part_filesrc = NULL;
|
||||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
|
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
|
||||||
target->appended_partitions[i] = NULL;
|
target->appended_partitions[i] = NULL;
|
||||||
if (opts->appended_partitions[i] != NULL) {
|
if (opts->appended_partitions[i] != NULL) {
|
||||||
@ -1857,6 +1977,35 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->appended_part_start[i] = target->appended_part_size[i] = 0;
|
target->appended_part_start[i] = target->appended_part_size[i] = 0;
|
||||||
}
|
}
|
||||||
strcpy(target->ascii_disc_label, opts->ascii_disc_label);
|
strcpy(target->ascii_disc_label, opts->ascii_disc_label);
|
||||||
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++) {
|
||||||
|
target->hfsplus_blessed[i] = src->hfsplus_blessed[i];
|
||||||
|
if (target->hfsplus_blessed[i] != NULL)
|
||||||
|
iso_node_ref(target->hfsplus_blessed[i]);
|
||||||
|
}
|
||||||
|
target->apm_block_size = opts->apm_block_size;
|
||||||
|
target->hfsp_block_size = opts->hfsp_block_size;
|
||||||
|
target->hfsp_cat_node_size = 0;
|
||||||
|
target->hfsp_iso_block_fac = 0;
|
||||||
|
target->hfsp_collision_count = 0;
|
||||||
|
target->apm_req_count = 0;
|
||||||
|
target->apm_req_flags = 0;
|
||||||
|
for (i = 0; i < ISO_APM_ENTRIES_MAX; i++)
|
||||||
|
target->apm_req[i] = NULL;
|
||||||
|
for (i = 0; i < ISO_MBR_ENTRIES_MAX; i++)
|
||||||
|
target->mbr_req[i] = NULL;
|
||||||
|
target->mbr_req_count = 0;
|
||||||
|
for (i = 0; i < ISO_GPT_ENTRIES_MAX; i++)
|
||||||
|
target->gpt_req[i] = NULL;
|
||||||
|
target->gpt_req_count = 0;
|
||||||
|
target->gpt_req_flags = 0;
|
||||||
|
target->gpt_part_start = 0;
|
||||||
|
target->gpt_backup_end = 0;
|
||||||
|
target->gpt_backup_size = 0;
|
||||||
|
target->gpt_max_entries = 0;
|
||||||
|
target->gpt_is_computed = 0;
|
||||||
|
|
||||||
|
target->filesrc_start = 0;
|
||||||
|
target->filesrc_blocks = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2. Based on those options, create needed writers: iso, joliet...
|
* 2. Based on those options, create needed writers: iso, joliet...
|
||||||
@ -1887,12 +2036,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (target->iso1999) {
|
if (target->iso1999) {
|
||||||
nwriters++;
|
nwriters++;
|
||||||
}
|
}
|
||||||
|
nwriters++; /* Partition Prepend writer */
|
||||||
|
if (target->hfsplus || target->fat) {
|
||||||
|
nwriters+= 2;
|
||||||
|
}
|
||||||
|
nwriters++; /* GPT backup tail writer */
|
||||||
nwriters++; /* Tail padding writer */
|
nwriters++; /* Tail padding writer */
|
||||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||||
nwriters++;
|
nwriters++;
|
||||||
image_checksums_mad = 1; /* from here on the loaded checksums are
|
|
||||||
not consistent with isofs.cx any more.
|
|
||||||
*/
|
|
||||||
ret = checksum_prepare_image(src, 0);
|
ret = checksum_prepare_image(src, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
@ -1922,7 +2073,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
el_torito_writer_index = target->nwriters - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create writer for Joliet structure */
|
/* create writer for Joliet structure */
|
||||||
@ -1960,6 +2110,25 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The writer for MBR and GPT partitions outside iso_file_src.
|
||||||
|
* If PreP or FAT are desired, it creates MBR partition entries and
|
||||||
|
* surrounding protecting partition entries.
|
||||||
|
* If EFI boot partition is desired, it creates a GPT entry for it.
|
||||||
|
*/
|
||||||
|
ret = partprepend_writer_create(target);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
|
||||||
|
/* create writer for HFS+/FAT structure */
|
||||||
|
/* Impotant: It must be created directly before iso_file_src_writer_create.
|
||||||
|
*/
|
||||||
|
if (target->hfsplus || target->fat) {
|
||||||
|
ret = hfsplus_writer_create(target);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* create writer for file contents */
|
/* create writer for file contents */
|
||||||
ret = iso_file_src_writer_create(target);
|
ret = iso_file_src_writer_create(target);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1967,18 +2136,73 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
}
|
}
|
||||||
file_src_writer_index = target->nwriters - 1;
|
file_src_writer_index = target->nwriters - 1;
|
||||||
|
|
||||||
|
/* create writer for HFS+ structure */
|
||||||
|
if (target->hfsplus || target->fat) {
|
||||||
|
ret = hfsplus_tail_writer_create(target);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* >>> Decide whether the GPT tail writer can be the last of all
|
||||||
|
*/
|
||||||
|
#define Libisofs_gpt_writer_lasT yes
|
||||||
|
|
||||||
|
#ifndef Libisofs_gpt_writer_lasT
|
||||||
|
/* This writer has to be added to the list after any writer which might
|
||||||
|
request production of APM or GPT partition entries by its
|
||||||
|
compute_data_blocks() method. Its compute_data_blocks() fills the gaps
|
||||||
|
in APM requests. It determines the position of primary GPT and
|
||||||
|
backup GPT. Further it reserves blocks for the backup GPT.
|
||||||
|
*/
|
||||||
|
ret = gpt_tail_writer_create(target);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
#endif /* ! Libisofs_gpt_writer_lasT */
|
||||||
|
|
||||||
|
|
||||||
|
/* >>> Should not the checksum writer come before the zero writer ?
|
||||||
|
*/
|
||||||
|
#define Libisofs_checksums_before_paddinG yes
|
||||||
|
#ifndef Libisofs_checksums_before_paddinG
|
||||||
|
|
||||||
|
/* >>> ??? Why is this important ? */
|
||||||
/* IMPORTANT: This must be the last writer before the checksum writer */
|
/* IMPORTANT: This must be the last writer before the checksum writer */
|
||||||
ret = zero_writer_create(target, target->tail_blocks, 1);
|
ret = zero_writer_create(target, target->tail_blocks, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
|
|
||||||
|
#endif /* !Libisofs_checksums_before_paddinG */
|
||||||
|
|
||||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||||
ret = checksum_writer_create(target);
|
ret = checksum_writer_create(target);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_checksums_before_paddinG
|
||||||
|
|
||||||
|
ret = zero_writer_create(target, target->tail_blocks, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
|
||||||
|
#endif /* Libisofs_checksums_before_paddinG */
|
||||||
|
|
||||||
|
#ifdef Libisofs_gpt_writer_lasT
|
||||||
|
/* This writer shall be the last one in the list, because it protects the
|
||||||
|
image on media which are seen as GPT partitioned.
|
||||||
|
In any case it has to come after any writer which might request
|
||||||
|
production of APM or GPT partition entries by its compute_data_blocks()
|
||||||
|
method.
|
||||||
|
gpt_tail_writer_compute_data_blocks() fills the gaps in APM requests.
|
||||||
|
It determines the position of primary GPT and backup GPT.
|
||||||
|
Further it reserves blocks for the backup GPT.
|
||||||
|
*/
|
||||||
|
ret = gpt_tail_writer_create(target);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
#endif /* Libisofs_gpt_writer_lasT */
|
||||||
|
|
||||||
if (target->partition_offset > 0) {
|
if (target->partition_offset > 0) {
|
||||||
/* After volume descriptors and superblock tag are accounted for:
|
/* After volume descriptors and superblock tag are accounted for:
|
||||||
account for second volset
|
account for second volset
|
||||||
@ -2012,6 +2236,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* At least the FAT computation needs to know the size of filesrc data
|
||||||
|
in advance. So this call produces target->filesrc_blocks and
|
||||||
|
relative extent addresses, which get absolute in
|
||||||
|
filesrc_writer_compute_data_blocks().
|
||||||
|
*/
|
||||||
|
ret = filesrc_writer_pre_compute(target->writers[file_src_writer_index]);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 3.
|
* 3.
|
||||||
* Call compute_data_blocks() in each Writer.
|
* Call compute_data_blocks() in each Writer.
|
||||||
@ -2021,10 +2254,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||||
IsoImageWriter *writer = target->writers[i];
|
IsoImageWriter *writer = target->writers[i];
|
||||||
|
|
||||||
/* Delaying boot image patching until new LBA is known */
|
|
||||||
if (i == el_torito_writer_index)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Exposing address of data start to IsoWriteOpts and memorizing
|
/* Exposing address of data start to IsoWriteOpts and memorizing
|
||||||
this address for all files which have no block address:
|
this address for all files which have no block address:
|
||||||
symbolic links, device files, empty data files.
|
symbolic links, device files, empty data files.
|
||||||
@ -2043,14 +2272,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now perform delayed image patching and System Area preparations */
|
ret = iso_patch_eltoritos(target);
|
||||||
if (el_torito_writer_index >= 0) {
|
if (ret < 0)
|
||||||
IsoImageWriter *writer = target->writers[el_torito_writer_index];
|
goto target_cleanup;
|
||||||
ret = writer->compute_data_blocks(writer);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto target_cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (((target->system_area_options & 0xfc) >> 2) == 2) {
|
if (((target->system_area_options & 0xfc) >> 2) == 2) {
|
||||||
ret = iso_read_mipsel_elf(target, 0);
|
ret = iso_read_mipsel_elf(target, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -2071,10 +2295,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
|
|
||||||
/* create the ring buffer */
|
/* create the ring buffer */
|
||||||
if (opts->overwrite != NULL &&
|
if (opts->overwrite != NULL &&
|
||||||
opts->fifo_size / 2048 < 32 + target->partition_offset) {
|
opts->fifo_size < 32 + target->partition_offset) {
|
||||||
/* The ring buffer must be large enough to take opts->overwrite
|
/* The ring buffer must be large enough to take opts->overwrite
|
||||||
*/
|
*/
|
||||||
ret = ISO_OVWRT_FIFO_TOO_SMALL;
|
ret = ISO_OVWRT_FIFO_TOO_SMALL;
|
||||||
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
ret = iso_ring_buffer_new(opts->fifo_size, &target->buffer);
|
ret = iso_ring_buffer_new(opts->fifo_size, &target->buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -2188,10 +2413,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
/* Dispose old image checksum buffer. The one of target is supposed to
|
|
||||||
get attached at the end of write_function(). */
|
if (target->apm_block_size == 0) {
|
||||||
iso_image_free_checksums(target->image, 0);
|
if (target->gpt_req_count)
|
||||||
image_checksums_mad = 0;
|
target->apm_block_size = 2048; /* Combinable with GPT */
|
||||||
|
else
|
||||||
|
target->apm_block_size = 512; /* Mountable on Linux */
|
||||||
|
}
|
||||||
|
|
||||||
/* ensure the thread is created joinable */
|
/* ensure the thread is created joinable */
|
||||||
pthread_attr_init(&(target->th_attr));
|
pthread_attr_init(&(target->th_attr));
|
||||||
@ -2232,9 +2460,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
*img = target;
|
*img = target;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
target_cleanup: ;
|
target_cleanup: ;
|
||||||
if(image_checksums_mad) /* No checksums is better than mad checksums */
|
|
||||||
iso_image_free_checksums(target->image, 0);
|
|
||||||
target->image->generator_is_running = 0;
|
target->image->generator_is_running = 0;
|
||||||
ecma119_image_free(target);
|
ecma119_image_free(target);
|
||||||
return ret;
|
return ret;
|
||||||
@ -2335,8 +2561,6 @@ int bs_set_size(struct burn_source *bs, off_t size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int dive_to_depth_8(IsoDir *dir, int depth)
|
int dive_to_depth_8(IsoDir *dir, int depth)
|
||||||
{
|
{
|
||||||
@ -2395,9 +2619,6 @@ int make_reloc_dir_if_needed(IsoImage *img, IsoWriteOpts *opts, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
|
|
||||||
int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
||||||
struct burn_source **burn_src)
|
struct burn_source **burn_src)
|
||||||
{
|
{
|
||||||
@ -2414,8 +2635,6 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
if (!opts->allow_deep_paths) {
|
if (!opts->allow_deep_paths) {
|
||||||
ret = make_reloc_dir_if_needed(image, opts, 0);
|
ret = make_reloc_dir_if_needed(image, opts, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -2424,8 +2643,6 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
ret = ecma119_image_new(image, opts, &target);
|
ret = ecma119_image_new(image, opts, &target);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(source);
|
free(source);
|
||||||
@ -2450,6 +2667,12 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (target->bytes_written + (off_t) count > target->total_size) {
|
||||||
|
iso_msg_submit(target->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
|
"ISO overwrite");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
ret = iso_ring_buffer_write(target->buffer, buf, count);
|
ret = iso_ring_buffer_write(target->buffer, buf, count);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* reader cancelled */
|
/* reader cancelled */
|
||||||
@ -2531,16 +2754,12 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
wopts->hfsplus = 0;
|
||||||
|
wopts->fat = 0;
|
||||||
wopts->fifo_size = 1024; /* 2 MB buffer */
|
wopts->fifo_size = 1024; /* 2 MB buffer */
|
||||||
wopts->sort_files = 1; /* file sorting is always good */
|
wopts->sort_files = 1; /* file sorting is always good */
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
wopts->rr_reloc_dir = NULL;
|
wopts->rr_reloc_dir = NULL;
|
||||||
wopts->rr_reloc_flags = 0;
|
wopts->rr_reloc_flags = 0;
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
wopts->system_area_data = NULL;
|
wopts->system_area_data = NULL;
|
||||||
wopts->system_area_options = 0;
|
wopts->system_area_options = 0;
|
||||||
wopts->vol_creation_time = 0;
|
wopts->vol_creation_time = 0;
|
||||||
@ -2557,6 +2776,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
#endif /* Libisofs_with_libjtE */
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
wopts->tail_blocks = 0;
|
wopts->tail_blocks = 0;
|
||||||
|
wopts->prep_partition = NULL;
|
||||||
|
wopts->efi_boot_partition = NULL;
|
||||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||||
wopts->appended_partitions[i] = NULL;
|
wopts->appended_partitions[i] = NULL;
|
||||||
wopts->ascii_disc_label[0] = 0;
|
wopts->ascii_disc_label[0] = 0;
|
||||||
@ -2564,6 +2785,10 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
wopts->allow_dir_id_ext = 0;
|
wopts->allow_dir_id_ext = 0;
|
||||||
wopts->old_empty = 0;
|
wopts->old_empty = 0;
|
||||||
wopts->untranslated_name_len = 0;
|
wopts->untranslated_name_len = 0;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
wopts->hfsp_serial_number[i] = 0;
|
||||||
|
wopts->apm_block_size = 0;
|
||||||
|
wopts->hfsp_block_size = 0;
|
||||||
|
|
||||||
*opts = wopts;
|
*opts = wopts;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -2577,16 +2802,14 @@ void iso_write_opts_free(IsoWriteOpts *opts)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
free(opts->output_charset);
|
free(opts->output_charset);
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
if (opts->rr_reloc_dir != NULL)
|
if (opts->rr_reloc_dir != NULL)
|
||||||
free(opts->rr_reloc_dir);
|
free(opts->rr_reloc_dir);
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
if (opts->system_area_data != NULL)
|
if (opts->system_area_data != NULL)
|
||||||
free(opts->system_area_data);
|
free(opts->system_area_data);
|
||||||
|
if (opts->prep_partition != NULL)
|
||||||
|
free(opts->prep_partition);
|
||||||
|
if (opts->efi_boot_partition != NULL)
|
||||||
|
free(opts->efi_boot_partition);
|
||||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||||
if (opts->appended_partitions[i] != NULL)
|
if (opts->appended_partitions[i] != NULL)
|
||||||
free(opts->appended_partitions[i]);
|
free(opts->appended_partitions[i]);
|
||||||
@ -2633,6 +2856,24 @@ int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_hfsplus(IsoWriteOpts *opts, int enable)
|
||||||
|
{
|
||||||
|
if (opts == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
opts->hfsplus = enable ? 1 : 0;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_fat(IsoWriteOpts *opts, int enable)
|
||||||
|
{
|
||||||
|
if (opts == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
opts->fat = enable ? 1 : 0;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable)
|
int iso_write_opts_set_iso1999(IsoWriteOpts *opts, int enable)
|
||||||
{
|
{
|
||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
@ -3062,8 +3303,9 @@ int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
|||||||
* ISOLINUX boot image (see iso_image_set_boot_image()) and
|
* ISOLINUX boot image (see iso_image_set_boot_image()) and
|
||||||
* only if not bit0 is set.
|
* only if not bit0 is set.
|
||||||
* bit2-7= System area type
|
* bit2-7= System area type
|
||||||
* 0= PC-BIOS DOS MBR
|
* bit8-9= Only with System area type 0 = MBR
|
||||||
* 1= MIPS Big Endian Volume Header
|
* Cylinder alignment mode
|
||||||
|
* bit10-13= System area sub type
|
||||||
* @param flag bit0 = invalidate any attached system area data
|
* @param flag bit0 = invalidate any attached system area data
|
||||||
* same as data == NULL
|
* same as data == NULL
|
||||||
* bit1 = keep data unaltered
|
* bit1 = keep data unaltered
|
||||||
@ -3085,7 +3327,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
|||||||
memcpy(opts->system_area_data, data, 32768);
|
memcpy(opts->system_area_data, data, 32768);
|
||||||
}
|
}
|
||||||
if (!(flag & 4))
|
if (!(flag & 4))
|
||||||
opts->system_area_options = options & 0x3ff;
|
opts->system_area_options = options & 0x7fff;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3151,19 +3393,44 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path, int flag)
|
||||||
|
{
|
||||||
|
if (opts->prep_partition != NULL)
|
||||||
|
free(opts->prep_partition);
|
||||||
|
if (image_path == NULL)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
opts->prep_partition = strdup(image_path);
|
||||||
|
if (opts->prep_partition == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
if (opts->efi_boot_partition != NULL)
|
||||||
|
free(opts->efi_boot_partition);
|
||||||
|
if (image_path == NULL)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
opts->efi_boot_partition = strdup(image_path);
|
||||||
|
if (opts->efi_boot_partition == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||||
uint8_t partition_type, char *image_path, int flag)
|
uint8_t partition_type, char *image_path, int flag)
|
||||||
{
|
{
|
||||||
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
|
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
|
||||||
return ISO_BAD_PARTITION_NO;
|
return ISO_BAD_PARTITION_NO;
|
||||||
|
|
||||||
if (opts->appended_partitions[partition_number - 1] != NULL)
|
if (opts->appended_partitions[partition_number - 1] != NULL)
|
||||||
free(opts->appended_partitions[partition_number - 1]);
|
free(opts->appended_partitions[partition_number - 1]);
|
||||||
|
if (image_path == NULL)
|
||||||
|
return ISO_SUCCESS;
|
||||||
opts->appended_partitions[partition_number - 1] = strdup(image_path);
|
opts->appended_partitions[partition_number - 1] = strdup(image_path);
|
||||||
if (opts->appended_partitions[partition_number - 1] == NULL)
|
if (opts->appended_partitions[partition_number - 1] == NULL)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
opts->appended_part_types[partition_number - 1] = partition_type;
|
opts->appended_part_types[partition_number - 1] = partition_type;
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3173,4 +3440,25 @@ int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
|
|||||||
opts->ascii_disc_label[ISO_DISC_LABEL_SIZE - 1] = 0;
|
opts->ascii_disc_label[ISO_DISC_LABEL_SIZE - 1] = 0;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
|
||||||
|
uint8_t serial_number[8])
|
||||||
|
{
|
||||||
|
memcpy(opts->hfsp_serial_number, serial_number, 8);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
|
||||||
|
int hfsp_block_size, int apm_block_size)
|
||||||
|
{
|
||||||
|
if (hfsp_block_size != 0 && hfsp_block_size != 512 &&
|
||||||
|
hfsp_block_size != 2048)
|
||||||
|
return ISO_BOOT_HFSP_BAD_BSIZE;
|
||||||
|
opts->hfsp_block_size = hfsp_block_size;
|
||||||
|
if (apm_block_size != 0 && apm_block_size != 512 && apm_block_size != 2048)
|
||||||
|
return ISO_BOOT_HFSP_BAD_BSIZE;
|
||||||
|
opts->apm_block_size = apm_block_size;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -70,6 +70,23 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The theoretical maximum number of Apple Partition Map entries in the
|
||||||
|
System Area of an ISO image:
|
||||||
|
Block0 plus 63 entries with block size 512
|
||||||
|
*/
|
||||||
|
#define ISO_APM_ENTRIES_MAX 63
|
||||||
|
|
||||||
|
/* The maximum number of MBR partition table entries.
|
||||||
|
*/
|
||||||
|
#define ISO_MBR_ENTRIES_MAX 4
|
||||||
|
|
||||||
|
/* The theoretical maximum number of GPT entries in the System Area of an
|
||||||
|
ISO image:
|
||||||
|
MBR plus GPT header block plus 248 GPT entries of 128 bytes each.
|
||||||
|
*/
|
||||||
|
#define ISO_GPT_ENTRIES_MAX 248
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the options for the image generation.
|
* Holds the options for the image generation.
|
||||||
*/
|
*/
|
||||||
@ -83,6 +100,8 @@ struct iso_write_opts {
|
|||||||
unsigned int rockridge :1;
|
unsigned int rockridge :1;
|
||||||
unsigned int joliet :1;
|
unsigned int joliet :1;
|
||||||
unsigned int iso1999 :1;
|
unsigned int iso1999 :1;
|
||||||
|
unsigned int hfsplus :1;
|
||||||
|
unsigned int fat :1;
|
||||||
|
|
||||||
unsigned int aaip :1; /* whether to write eventual ACL and EAs */
|
unsigned int aaip :1; /* whether to write eventual ACL and EAs */
|
||||||
|
|
||||||
@ -433,6 +452,16 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
uint32_t tail_blocks;
|
uint32_t tail_blocks;
|
||||||
|
|
||||||
|
/* Eventual disk file path of a PreP partition which shall be prepended
|
||||||
|
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
|
||||||
|
*/
|
||||||
|
char *prep_partition;
|
||||||
|
|
||||||
|
/* Eventual disk file path of an EFI system partition image which shall
|
||||||
|
be prepended to HFS+/FAT and IsoFileSrc areas and marked by a GPT entry.
|
||||||
|
*/
|
||||||
|
char *efi_boot_partition;
|
||||||
|
|
||||||
/* Eventual disk file paths of prepared images which shall be appended
|
/* Eventual disk file paths of prepared images which shall be appended
|
||||||
after the ISO image and described by partiton table entries in a MBR
|
after the ISO image and described by partiton table entries in a MBR
|
||||||
*/
|
*/
|
||||||
@ -442,12 +471,27 @@ struct iso_write_opts {
|
|||||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||||
*/
|
*/
|
||||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||||
|
|
||||||
|
/* HFS+ image serial number.
|
||||||
|
* 00...00 means that it shall be generated by libisofs.
|
||||||
|
*/
|
||||||
|
uint8_t hfsp_serial_number[8];
|
||||||
|
|
||||||
|
/* Allocation block size of HFS+ : 0= auto , 512, or 2048
|
||||||
|
*/
|
||||||
|
int hfsp_block_size;
|
||||||
|
|
||||||
|
/* Block size of and in APM : 0= auto , 512, or 2048
|
||||||
|
*/
|
||||||
|
int apm_block_size;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
typedef struct ecma119_node Ecma119Node;
|
typedef struct ecma119_node Ecma119Node;
|
||||||
typedef struct joliet_node JolietNode;
|
typedef struct joliet_node JolietNode;
|
||||||
typedef struct iso1999_node Iso1999Node;
|
typedef struct iso1999_node Iso1999Node;
|
||||||
|
typedef struct hfsplus_node HFSPlusNode;
|
||||||
typedef struct Iso_File_Src IsoFileSrc;
|
typedef struct Iso_File_Src IsoFileSrc;
|
||||||
typedef struct Iso_Image_Writer IsoImageWriter;
|
typedef struct Iso_Image_Writer IsoImageWriter;
|
||||||
|
|
||||||
@ -467,6 +511,8 @@ struct ecma119_image
|
|||||||
unsigned int joliet :1;
|
unsigned int joliet :1;
|
||||||
unsigned int eltorito :1;
|
unsigned int eltorito :1;
|
||||||
unsigned int iso1999 :1;
|
unsigned int iso1999 :1;
|
||||||
|
unsigned int hfsplus :1;
|
||||||
|
unsigned int fat :1;
|
||||||
|
|
||||||
unsigned int hardlinks:1; /* see iso_write_opts_set_hardlinks() */
|
unsigned int hardlinks:1; /* see iso_write_opts_set_hardlinks() */
|
||||||
|
|
||||||
@ -544,6 +590,11 @@ struct ecma119_image
|
|||||||
char *input_charset;
|
char *input_charset;
|
||||||
char *output_charset;
|
char *output_charset;
|
||||||
|
|
||||||
|
/* See iso_write_opts and iso_write_opts_set_hfsp_serial_number().
|
||||||
|
* 00...00 means that it shall be generated by libisofs.
|
||||||
|
*/
|
||||||
|
uint8_t hfsp_serial_number[8];
|
||||||
|
|
||||||
unsigned int appendable : 1;
|
unsigned int appendable : 1;
|
||||||
uint32_t ms_block; /**< start block for a ms image */
|
uint32_t ms_block; /**< start block for a ms image */
|
||||||
time_t now; /**< Time at which writing began. */
|
time_t now; /**< Time at which writing began. */
|
||||||
@ -592,6 +643,29 @@ struct ecma119_image
|
|||||||
uint32_t joliet_l_path_table_pos;
|
uint32_t joliet_l_path_table_pos;
|
||||||
uint32_t joliet_m_path_table_pos;
|
uint32_t joliet_m_path_table_pos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HFS+ related information
|
||||||
|
* (by Vladimir Serbinenko, see libisofs/hfsplus.c)
|
||||||
|
*/
|
||||||
|
HFSPlusNode *hfsp_leafs;
|
||||||
|
struct hfsplus_btree_level *hfsp_levels;
|
||||||
|
uint32_t hfsp_nlevels;
|
||||||
|
uint32_t hfsp_part_start;
|
||||||
|
uint32_t hfsp_nfiles;
|
||||||
|
uint32_t hfsp_ndirs;
|
||||||
|
uint32_t hfsp_cat_id;
|
||||||
|
uint32_t hfsp_allocation_blocks;
|
||||||
|
uint32_t hfsp_allocation_file_start;
|
||||||
|
uint32_t hfsp_extent_file_start;
|
||||||
|
uint32_t hfsp_catalog_file_start;
|
||||||
|
uint32_t hfsp_total_blocks;
|
||||||
|
uint32_t hfsp_allocation_size;
|
||||||
|
uint32_t hfsp_nleafs;
|
||||||
|
uint32_t hfsp_curleaf;
|
||||||
|
uint32_t hfsp_nnodes;
|
||||||
|
uint32_t hfsp_bless_id[ISO_HFSPLUS_BLESS_MAX];
|
||||||
|
uint32_t hfsp_collision_count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ISO 9660:1999 related information
|
* ISO 9660:1999 related information
|
||||||
*/
|
*/
|
||||||
@ -639,6 +713,15 @@ struct ecma119_image
|
|||||||
* 0 = auto (align if bit1)
|
* 0 = auto (align if bit1)
|
||||||
* 1 = always align to cylinder boundary
|
* 1 = always align to cylinder boundary
|
||||||
* 2 = never align to cylinder boundary
|
* 2 = never align to cylinder boundary
|
||||||
|
* 3 = always align, additionally pad up and align partitions
|
||||||
|
* which were appended by iso_write_opts_set_partition_img()
|
||||||
|
* bit10-13= System area sub type
|
||||||
|
* With type 0 = MBR:
|
||||||
|
* Gets overridden by bit0 and bit1.
|
||||||
|
* 0 = no particular sub type
|
||||||
|
* 1 = CHRP: A single MBR partition of type 0x96 covers the
|
||||||
|
* ISO image. Not compatible with any other feature
|
||||||
|
* which needs to have own MBR partition entries.
|
||||||
*/
|
*/
|
||||||
int system_area_options;
|
int system_area_options;
|
||||||
|
|
||||||
@ -742,6 +825,11 @@ struct ecma119_image
|
|||||||
uint32_t mipsel_p_vaddr;
|
uint32_t mipsel_p_vaddr;
|
||||||
uint32_t mipsel_p_filesz;
|
uint32_t mipsel_p_filesz;
|
||||||
|
|
||||||
|
/* A data file of which the position and size shall be written after
|
||||||
|
a SUN Disk Label.
|
||||||
|
*/
|
||||||
|
IsoFileSrc *sparc_core_src;
|
||||||
|
|
||||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||||
/* Counted in blocks of 2048 */
|
/* Counted in blocks of 2048 */
|
||||||
@ -751,6 +839,84 @@ struct ecma119_image
|
|||||||
|
|
||||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||||
|
|
||||||
|
/* See IsoImage and libisofs.h */
|
||||||
|
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||||
|
|
||||||
|
/* Block sizes come from write options.
|
||||||
|
Only change a block size if it is 0. Set only to 512 or 2048.
|
||||||
|
If it stays 0 then it will become 512 or 2048 in time.
|
||||||
|
*/
|
||||||
|
/* Blocksize of Apple Partition Map
|
||||||
|
May be defined to 512 or 2048 before writer thread starts.
|
||||||
|
*/
|
||||||
|
int apm_block_size;
|
||||||
|
|
||||||
|
/* Allocation block size of HFS+
|
||||||
|
May be defined to 512 or 2048 before hfsplus_writer_create().
|
||||||
|
*/
|
||||||
|
int hfsp_block_size;
|
||||||
|
int hfsp_cat_node_size; /* 2 * apm_block_size */
|
||||||
|
int hfsp_iso_block_fac; /* 2048 / apm_block_size */
|
||||||
|
|
||||||
|
/* Apple Partition Map description. To be composed during IsoImageWriter
|
||||||
|
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
||||||
|
Make sure that the composing writers get registered before the
|
||||||
|
gpt_tail_writer.
|
||||||
|
*/
|
||||||
|
struct iso_apm_partition_request *apm_req[ISO_APM_ENTRIES_MAX];
|
||||||
|
int apm_req_count;
|
||||||
|
/* bit1= Do not fill gaps in Apple Partition Map
|
||||||
|
bit2= apm_req entries use apm_block_size in start_block and block_count.
|
||||||
|
Normally these two parameters are counted in 2 KiB blocks.
|
||||||
|
*/
|
||||||
|
int apm_req_flags;
|
||||||
|
|
||||||
|
/* MBR partition table description. To be composed during IsoImageWriter
|
||||||
|
method ->compute_data_blocks() by calling iso_register_mbr_entry().
|
||||||
|
*/
|
||||||
|
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
|
||||||
|
int mbr_req_count;
|
||||||
|
|
||||||
|
char *prep_partition;
|
||||||
|
uint32_t prep_part_size;
|
||||||
|
|
||||||
|
/* GPT description. To be composed during IsoImageWriter
|
||||||
|
method ->compute_data_blocks() by calling iso_register_gpt_entry().
|
||||||
|
Make sure that the composing writers get registered before the
|
||||||
|
gpt_tail_writer.
|
||||||
|
*/
|
||||||
|
struct iso_gpt_partition_request *gpt_req[ISO_GPT_ENTRIES_MAX];
|
||||||
|
int gpt_req_count;
|
||||||
|
/* bit0= GPT partitions may overlap */
|
||||||
|
int gpt_req_flags;
|
||||||
|
|
||||||
|
char *efi_boot_partition;
|
||||||
|
uint32_t efi_boot_part_size;
|
||||||
|
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
|
||||||
|
|
||||||
|
/* Messages from gpt_tail_writer_compute_data_blocks() to
|
||||||
|
iso_write_system_area().
|
||||||
|
*/
|
||||||
|
/* Start of GPT entries in System Area, block size 512 */
|
||||||
|
uint32_t gpt_part_start;
|
||||||
|
/* The ISO block number after the backup GPT header , block size 2048 */
|
||||||
|
uint32_t gpt_backup_end;
|
||||||
|
uint32_t gpt_backup_size;
|
||||||
|
uint32_t gpt_max_entries;
|
||||||
|
int gpt_is_computed;
|
||||||
|
|
||||||
|
/* Message from write_head_part1()/iso_write_system_area() to the
|
||||||
|
write_data() methods of the writers.
|
||||||
|
*/
|
||||||
|
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
|
||||||
|
|
||||||
|
/* Size of the filesrc_writer area (data file content).
|
||||||
|
This is available before any IsoImageWriter.compute_data_blocks()
|
||||||
|
is called.
|
||||||
|
*/
|
||||||
|
uint32_t filesrc_start;
|
||||||
|
uint32_t filesrc_blocks;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BP(a,b) [(b) - (a) + 1]
|
#define BP(a,b) [(b) - (a) + 1]
|
||||||
@ -881,5 +1047,11 @@ struct ecma119_vol_desc_terminator
|
|||||||
uint8_t reserved BP(8, 2048);
|
uint8_t reserved BP(8, 2048);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ecma119_set_voldescr_times(IsoImageWriter *writer,
|
||||||
|
struct ecma119_pri_vol_desc *vol);
|
||||||
|
|
||||||
|
/* Copies a data file into the ISO image output stream */
|
||||||
|
int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||||
|
uint32_t prepad, uint32_t blocks, int flag);
|
||||||
|
|
||||||
#endif /*LIBISO_ECMA119_H_*/
|
#endif /*LIBISO_ECMA119_H_*/
|
||||||
|
@ -153,16 +153,10 @@ needs_transl:;
|
|||||||
|
|
||||||
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
|
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
if (img->rr_reloc_node == node &&
|
if (img->rr_reloc_node == node &&
|
||||||
node != img->root && node != img->partition_root &&
|
node != img->root && node != img->partition_root &&
|
||||||
(img->rr_reloc_flags & 2))
|
(img->rr_reloc_flags & 2))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,9 +468,6 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
if (depth == 1) { /* root is default */
|
if (depth == 1) { /* root is default */
|
||||||
image->rr_reloc_node = node;
|
image->rr_reloc_node = node;
|
||||||
} else if (depth == 2) {
|
} else if (depth == 2) {
|
||||||
@ -486,10 +477,6 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
strcmp(iso->name, image->rr_reloc_dir) == 0)
|
strcmp(iso->name, image->rr_reloc_dir) == 0)
|
||||||
image->rr_reloc_node = node;
|
image->rr_reloc_node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
pos = dir->children;
|
pos = dir->children;
|
||||||
@ -734,8 +721,11 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
goto mangle_cleanup;
|
goto mangle_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_extra_verbose_debuG
|
||||||
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
|
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
|
||||||
children[k]->iso_name, new);
|
children[k]->iso_name, new);
|
||||||
|
#endif
|
||||||
|
|
||||||
iso_htable_remove_ptr(table, children[k]->iso_name, NULL);
|
iso_htable_remove_ptr(table, children[k]->iso_name, NULL);
|
||||||
free(children[k]->iso_name);
|
free(children[k]->iso_name);
|
||||||
@ -959,9 +949,6 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
|
|||||||
max_path = pathlen + 1 + max_child_name_len(dir);
|
max_path = pathlen + 1 + max_child_name_len(dir);
|
||||||
|
|
||||||
if (level > 8 || max_path > 255) {
|
if (level > 8 || max_path > 255) {
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
reloc = img->rr_reloc_node;
|
reloc = img->rr_reloc_node;
|
||||||
if (reloc == NULL) {
|
if (reloc == NULL) {
|
||||||
if (img->eff_partition_offset > 0) {
|
if (img->eff_partition_offset > 0) {
|
||||||
@ -970,17 +957,6 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
|
|||||||
reloc = img->root;
|
reloc = img->root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (img->eff_partition_offset > 0) {
|
|
||||||
reloc = img->partition_root;
|
|
||||||
} else {
|
|
||||||
reloc = img->root;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
ret = reparent(dir, reloc);
|
ret = reparent(dir, reloc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@ -1235,13 +1211,7 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
* above could insert new directories into the relocation directory.
|
* above could insert new directories into the relocation directory.
|
||||||
* Note that recurse = 0, as we don't need to recurse.
|
* Note that recurse = 0, as we don't need to recurse.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
ret = mangle_tree(img, img->rr_reloc_node, 0);
|
ret = mangle_tree(img, img->rr_reloc_node, 0);
|
||||||
#else
|
|
||||||
ret = mangle_tree(img, NULL, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2010 Thomas Schmitt
|
* Copyright (c) 2010 - 2013 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -160,7 +160,13 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
|
|||||||
/* API */
|
/* API */
|
||||||
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
|
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
|
||||||
{
|
{
|
||||||
return bootimg->seems_boot_info_table;
|
switch (flag & 15) {
|
||||||
|
case 0:
|
||||||
|
return bootimg->seems_boot_info_table;
|
||||||
|
case 1:
|
||||||
|
return bootimg->seems_grub2_boot_info;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,14 +203,14 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
|
|||||||
*/
|
*/
|
||||||
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
||||||
{
|
{
|
||||||
bootimg->isolinux_options = (options & 0x03);
|
bootimg->isolinux_options = (options & 0x03ff);
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
|
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
|
||||||
{
|
{
|
||||||
return bootimg->isolinux_options & 0x03;
|
return bootimg->isolinux_options & 0x03ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
@ -306,7 +312,8 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||||||
static
|
static
|
||||||
int create_image(IsoImage *image, const char *image_path,
|
int create_image(IsoImage *image, const char *image_path,
|
||||||
enum eltorito_boot_media_type type,
|
enum eltorito_boot_media_type type,
|
||||||
struct el_torito_boot_image **bootimg)
|
struct el_torito_boot_image **bootimg,
|
||||||
|
IsoFile **bootnode)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct el_torito_boot_image *boot;
|
struct el_torito_boot_image *boot;
|
||||||
@ -317,6 +324,7 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
IsoNode *imgfile;
|
IsoNode *imgfile;
|
||||||
IsoStream *stream;
|
IsoStream *stream;
|
||||||
|
|
||||||
|
*bootnode = NULL;
|
||||||
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@ -331,6 +339,7 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
if (imgfile->type != LIBISO_FILE) {
|
if (imgfile->type != LIBISO_FILE) {
|
||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
}
|
}
|
||||||
|
*bootnode = (IsoFile *) imgfile;
|
||||||
|
|
||||||
stream = ((IsoFile*)imgfile)->stream;
|
stream = ((IsoFile*)imgfile)->stream;
|
||||||
|
|
||||||
@ -455,6 +464,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
struct el_torito_boot_catalog *catalog;
|
struct el_torito_boot_catalog *catalog;
|
||||||
ElToritoBootImage *boot_image= NULL;
|
ElToritoBootImage *boot_image= NULL;
|
||||||
IsoBoot *cat_node= NULL;
|
IsoBoot *cat_node= NULL;
|
||||||
|
IsoFile *boot_node;
|
||||||
|
|
||||||
if (image == NULL || image_path == NULL || catalog_path == NULL) {
|
if (image == NULL || image_path == NULL || catalog_path == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -507,7 +517,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create the boot image */
|
/* create the boot image */
|
||||||
ret = create_image(image, image_path, type, &boot_image);
|
ret = create_image(image, image_path, type, &boot_image, &boot_node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto boot_image_cleanup;
|
goto boot_image_cleanup;
|
||||||
}
|
}
|
||||||
@ -524,6 +534,8 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
catalog->bootimages[i] = NULL;
|
catalog->bootimages[i] = NULL;
|
||||||
catalog->node = cat_node;
|
catalog->node = cat_node;
|
||||||
catalog->sort_weight = 1000; /* slightly high */
|
catalog->sort_weight = 1000; /* slightly high */
|
||||||
|
if (!boot_node->explicit_weight)
|
||||||
|
boot_node->sort_weight = 2;
|
||||||
iso_node_ref((IsoNode*)cat_node);
|
iso_node_ref((IsoNode*)cat_node);
|
||||||
image->bootcat = catalog;
|
image->bootcat = catalog;
|
||||||
|
|
||||||
@ -694,14 +706,17 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
|||||||
int ret;
|
int ret;
|
||||||
struct el_torito_boot_catalog *catalog = image->bootcat;
|
struct el_torito_boot_catalog *catalog = image->bootcat;
|
||||||
ElToritoBootImage *boot_img;
|
ElToritoBootImage *boot_img;
|
||||||
|
IsoFile *boot_node;
|
||||||
|
|
||||||
if(catalog == NULL)
|
if(catalog == NULL)
|
||||||
return ISO_BOOT_NO_CATALOG;
|
return ISO_BOOT_NO_CATALOG;
|
||||||
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
|
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
|
||||||
return ISO_BOOT_IMAGE_OVERFLOW;
|
return ISO_BOOT_IMAGE_OVERFLOW;
|
||||||
ret = create_image(image, image_path, type, &boot_img);
|
ret = create_image(image, image_path, type, &boot_img, &boot_node);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
if (!boot_node->explicit_weight)
|
||||||
|
boot_node->sort_weight = 2;
|
||||||
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
||||||
catalog->num_bootimages++;
|
catalog->num_bootimages++;
|
||||||
if (boot != NULL)
|
if (boot != NULL)
|
||||||
@ -1032,7 +1047,7 @@ int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fill fields */
|
/* fill fields */
|
||||||
file->prev_img = 0; /* TODO allow copy of old img catalog???? */
|
file->no_write = 0; /* TODO allow copy of old img catalog???? */
|
||||||
file->checksum_index = 0;
|
file->checksum_index = 0;
|
||||||
file->nsections = 1;
|
file->nsections = 1;
|
||||||
file->sections = calloc(1, sizeof(struct iso_file_section));
|
file->sections = calloc(1, sizeof(struct iso_file_section));
|
||||||
@ -1096,13 +1111,14 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch an isolinux boot image.
|
* Patch an El Torito boot image by a boot info table.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 on success, 0 error (but continue), < 0 error
|
* 1 on success, 0 error (but continue), < 0 error
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
|
int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
|
||||||
|
size_t imgsize, int idx)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1116,29 +1132,41 @@ int patch_boot_image(uint8_t *buf, Ecma119Image *t, size_t imgsize, int idx)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch a GRUB2 El Torito boot image.
|
||||||
|
*/
|
||||||
static
|
static
|
||||||
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
|
||||||
|
size_t imgsize, int idx,
|
||||||
|
size_t pos, int offst)
|
||||||
|
{
|
||||||
|
uint64_t blk;
|
||||||
|
|
||||||
|
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.");
|
||||||
|
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);
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Patch the boot images if indicated */
|
||||||
|
int iso_patch_eltoritos(Ecma119Image *t)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* We have nothing to write, but if we need to patch an isolinux image,
|
|
||||||
* this is a good place to do so.
|
|
||||||
*/
|
|
||||||
Ecma119Image *t;
|
|
||||||
int ret, idx;
|
int ret, idx;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
IsoStream *new = NULL;
|
IsoStream *new = NULL;
|
||||||
IsoStream *original = NULL;
|
IsoStream *original = NULL;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (t->catalog == NULL)
|
||||||
return ISO_NULL_POINTER;
|
return ISO_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
t = writer->target;
|
|
||||||
|
|
||||||
/* Patch the boot image info tables if indicated */
|
|
||||||
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
||||||
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
|
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
|
||||||
continue;
|
continue;
|
||||||
original = t->bootsrc[idx]->stream;
|
original = t->bootsrc[idx]->stream;
|
||||||
size = (size_t) iso_stream_get_size(original);
|
size = (size_t) iso_stream_get_size(original);
|
||||||
@ -1162,9 +1190,20 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ok, patch the read buffer */
|
/* ok, patch the read buffer */
|
||||||
ret = patch_boot_image(buf, t, size, idx);
|
if (t->catalog->bootimages[idx]->isolinux_options & 0x200) {
|
||||||
if (ret < 0) {
|
/* GRUB2 boot provisions */
|
||||||
return ret;
|
ret = patch_grub2_boot_image(buf, t, size, idx,
|
||||||
|
Libisofs_grub2_elto_patch_poS,
|
||||||
|
Libisofs_grub2_elto_patch_offsT);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* Must be done as last patching */
|
||||||
|
if (t->catalog->bootimages[idx]->isolinux_options & 0x01) {
|
||||||
|
/* Boot Info Table */
|
||||||
|
ret = patch_boot_info_table(buf, t, size, idx);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* replace the original stream with a memory stream that reads from
|
/* replace the original stream with a memory stream that reads from
|
||||||
@ -1179,6 +1218,16 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We have nothing to write.
|
||||||
|
*/
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the Boot Record Volume Descriptor (ECMA-119, 8.2)
|
* Write the Boot Record Volume Descriptor (ECMA-119, 8.2)
|
||||||
*/
|
*/
|
||||||
@ -1221,7 +1270,7 @@ int eltorito_writer_free_data(IsoImageWriter *writer)
|
|||||||
|
|
||||||
int eltorito_writer_create(Ecma119Image *target)
|
int eltorito_writer_create(Ecma119Image *target)
|
||||||
{
|
{
|
||||||
int ret, idx;
|
int ret, idx, outsource_efi = 0;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
IsoFile *bootimg;
|
IsoFile *bootimg;
|
||||||
IsoFileSrc *src;
|
IsoFileSrc *src;
|
||||||
@ -1253,6 +1302,9 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target->efi_boot_partition != NULL)
|
||||||
|
if (strcmp(target->efi_boot_partition, "--efi-boot-image") == 0)
|
||||||
|
outsource_efi = 1;
|
||||||
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
||||||
bootimg = target->catalog->bootimages[idx]->image;
|
bootimg = target->catalog->bootimages[idx]->image;
|
||||||
ret = iso_file_src_create(target, bootimg, &src);
|
ret = iso_file_src_create(target, bootimg, &src);
|
||||||
@ -1263,12 +1315,35 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
/* For patching an image, it needs to be copied always */
|
/* For patching an image, it needs to be copied always */
|
||||||
if (target->catalog->bootimages[idx]->isolinux_options & 0x01) {
|
if (target->catalog->bootimages[idx]->isolinux_options & 0x01) {
|
||||||
src->prev_img = 0;
|
src->no_write = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If desired: Recognize first EFI boot image that will be newly
|
||||||
|
written, and mark it as claimed for being a partition.
|
||||||
|
*/
|
||||||
|
if (outsource_efi &&
|
||||||
|
target->catalog->bootimages[idx]->platform_id == 0xef &&
|
||||||
|
src->no_write == 0) {
|
||||||
|
target->efi_boot_part_filesrc = src;
|
||||||
|
src->sections[0].block = 0xfffffffe;
|
||||||
|
((IsoNode *) bootimg)->hidden |=
|
||||||
|
LIBISO_HIDE_ON_HFSPLUS | LIBISO_HIDE_ON_FAT;
|
||||||
|
outsource_efi = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need the bootable volume descriptor */
|
/* we need the bootable volume descriptor */
|
||||||
target->curblock++;
|
target->curblock++;
|
||||||
|
|
||||||
|
if (outsource_efi) {
|
||||||
|
/* Disable EFI Boot partition and complain */
|
||||||
|
free(target->efi_boot_partition);
|
||||||
|
target->efi_boot_partition = NULL;
|
||||||
|
iso_msg_submit(target->image->id, ISO_BOOT_NO_EFI_ELTO, 0,
|
||||||
|
"No newly added El Torito EFI boot image found for exposure as GPT partition");
|
||||||
|
return ISO_BOOT_NO_EFI_ELTO;
|
||||||
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,13 +58,20 @@ struct el_torito_boot_image {
|
|||||||
* Whether the boot image seems to contain a boot_info_table
|
* Whether the boot image seems to contain a boot_info_table
|
||||||
*/
|
*/
|
||||||
unsigned int seems_boot_info_table:1;
|
unsigned int seems_boot_info_table:1;
|
||||||
|
unsigned int seems_grub2_boot_info:1;
|
||||||
/**
|
/**
|
||||||
* isolinux options
|
* isolinux options
|
||||||
* bit 0 -> whether to patch image
|
* bit 0 -> whether to patch image
|
||||||
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
|
* bit 1 -> whether to put built-in isolinux 3.72 isohybrid-MBR into image
|
||||||
* System Area (deprecated)
|
* System Area (deprecated)
|
||||||
|
*
|
||||||
|
* bit2-7= Mentioning in isohybrid GPT
|
||||||
|
* 0= do not mention in GPT
|
||||||
|
* 1= mention as EFI partition
|
||||||
|
* 2= Mention as HFS+ partition
|
||||||
|
* bit8= Mention in isohybrid Apple partition map
|
||||||
*/
|
*/
|
||||||
unsigned int isolinux_options:2;
|
unsigned int isolinux_options;
|
||||||
unsigned char type; /**< The type of image */
|
unsigned char type; /**< The type of image */
|
||||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||||
short load_seg; /**< Load segment for the initial boot image. */
|
short load_seg; /**< Load segment for the initial boot image. */
|
||||||
@ -75,6 +82,7 @@ struct el_torito_boot_image {
|
|||||||
uint8_t platform_id;
|
uint8_t platform_id;
|
||||||
uint8_t id_string[28];
|
uint8_t id_string[28];
|
||||||
uint8_t selection_crit[20];
|
uint8_t selection_crit[20];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** El-Torito, 2.1 */
|
/** El-Torito, 2.1 */
|
||||||
@ -144,5 +152,16 @@ int eltorito_writer_create(Ecma119Image *target);
|
|||||||
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
|
int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
|
||||||
uint32_t boot_lba, uint32_t imgsize);
|
uint32_t boot_lba, uint32_t imgsize);
|
||||||
|
|
||||||
|
/* Patch the boot images if indicated.
|
||||||
|
*/
|
||||||
|
int iso_patch_eltoritos(Ecma119Image *t);
|
||||||
|
|
||||||
|
|
||||||
|
/* Parameters for patch_grub2_boot_image()
|
||||||
|
Might later become variables in struct el_torito_boot_image.
|
||||||
|
*/
|
||||||
|
#define Libisofs_grub2_elto_patch_poS (512 * 5 - 12)
|
||||||
|
#define Libisofs_grub2_elto_patch_offsT 5
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIBISO_ELTORITO_H */
|
#endif /* LIBISO_ELTORITO_H */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* 2010 - 2011 Thomas Schmitt
|
* 2010 - 2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -68,7 +68,7 @@ int iso_file_src_cmp(const void *n1, const void *n2)
|
|||||||
|
|
||||||
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
IsoFileSrc *fsrc;
|
IsoFileSrc *fsrc;
|
||||||
unsigned int fs_id;
|
unsigned int fs_id;
|
||||||
dev_t dev_id;
|
dev_t dev_id;
|
||||||
@ -88,7 +88,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fill key and other atts */
|
/* fill key and other atts */
|
||||||
fsrc->prev_img = file->from_old_session;
|
fsrc->no_write = (file->from_old_session && img->appendable);
|
||||||
if (file->from_old_session && img->appendable) {
|
if (file->from_old_session && img->appendable) {
|
||||||
/*
|
/*
|
||||||
* On multisession discs we keep file sections from old image.
|
* On multisession discs we keep file sections from old image.
|
||||||
@ -112,7 +112,14 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
} else {
|
} else {
|
||||||
fsrc->nsections = 1;
|
fsrc->nsections = 1;
|
||||||
}
|
}
|
||||||
fsrc->sections = calloc(fsrc->nsections, sizeof(struct iso_file_section));
|
fsrc->sections = calloc(fsrc->nsections,
|
||||||
|
sizeof(struct iso_file_section));
|
||||||
|
if (fsrc->sections == NULL) {
|
||||||
|
free(fsrc);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
for (i = 0; i < fsrc->nsections; i++)
|
||||||
|
fsrc->sections[i].block = 0;
|
||||||
}
|
}
|
||||||
fsrc->sort_weight = file->sort_weight;
|
fsrc->sort_weight = file->sort_weight;
|
||||||
fsrc->stream = file->stream;
|
fsrc->stream = file->stream;
|
||||||
@ -120,7 +127,7 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
/* insert the filesrc in the tree */
|
/* insert the filesrc in the tree */
|
||||||
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
|
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
if (ret == 0 && (*src)->checksum_index > 0) {
|
if (ret == 0 && (*src)->checksum_index > 0 && !img->will_cancel) {
|
||||||
/* Duplicate file source was mapped to previously registered source
|
/* Duplicate file source was mapped to previously registered source
|
||||||
*/
|
*/
|
||||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||||
@ -145,13 +152,13 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
|||||||
no_md5 = 1;
|
no_md5 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((img->md5_file_checksums & 1) && !no_md5) {
|
if ((img->md5_file_checksums & 1) && !(no_md5 || img->will_cancel)) {
|
||||||
img->checksum_idx_counter++;
|
img->checksum_idx_counter++;
|
||||||
if (img->checksum_idx_counter < 0x7fffffff) {
|
if (img->checksum_idx_counter < 0x7fffffff) {
|
||||||
fsrc->checksum_index = img->checksum_idx_counter;
|
fsrc->checksum_index = img->checksum_idx_counter;
|
||||||
} else {
|
} else {
|
||||||
fsrc->checksum_index= 0;
|
fsrc->checksum_index= 0;
|
||||||
img->checksum_idx_counter= 0x7fffffff; /* keep from rolling over */
|
img->checksum_idx_counter= 0x7ffffffe; /* keep from rolling over */
|
||||||
}
|
}
|
||||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||||
if (cret < 0)
|
if (cret < 0)
|
||||||
@ -214,16 +221,15 @@ static int cmp_by_weight(const void *f1, const void *f2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int is_ms_file(void *arg)
|
int shall_be_written(void *arg)
|
||||||
{
|
{
|
||||||
IsoFileSrc *f = (IsoFileSrc *)arg;
|
IsoFileSrc *f = (IsoFileSrc *)arg;
|
||||||
return f->prev_img ? 0 : 1;
|
return f->no_write ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
int filesrc_writer_pre_compute(IsoImageWriter *writer)
|
||||||
int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|
||||||
{
|
{
|
||||||
size_t i, size;
|
size_t i, size, is_external;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
IsoFileSrc **filelist;
|
IsoFileSrc **filelist;
|
||||||
int (*inc_item)(void *);
|
int (*inc_item)(void *);
|
||||||
@ -233,16 +239,17 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
t->filesrc_blocks = 0;
|
||||||
|
|
||||||
/* Normally reserve a single zeroed block for all files which have
|
/* Normally reserve a single zeroed block for all files which have
|
||||||
no block address: symbolic links, device files, empty data files.
|
no block address: symbolic links, device files, empty data files.
|
||||||
*/
|
*/
|
||||||
if (! t->old_empty)
|
if (! t->old_empty)
|
||||||
t->curblock++;
|
t->filesrc_blocks++;
|
||||||
|
|
||||||
/* on appendable images, ms files shouldn't be included */
|
/* on appendable images, ms files shouldn't be included */
|
||||||
if (t->appendable) {
|
if (t->appendable) {
|
||||||
inc_item = is_ms_file;
|
inc_item = shall_be_written;
|
||||||
} else {
|
} else {
|
||||||
inc_item = NULL;
|
inc_item = NULL;
|
||||||
}
|
}
|
||||||
@ -262,10 +269,18 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
for (i = 0; i < size; ++i) {
|
for (i = 0; i < size; ++i) {
|
||||||
int extent = 0;
|
int extent = 0;
|
||||||
IsoFileSrc *file = filelist[i];
|
IsoFileSrc *file = filelist[i];
|
||||||
|
off_t section_size;
|
||||||
|
|
||||||
off_t section_size = iso_stream_get_size(file->stream);
|
/* 0xfffffffe in emerging image means that this is an external
|
||||||
|
partition. Only assess extent sizes but do not count as part
|
||||||
|
of filesrc_writer output.
|
||||||
|
*/
|
||||||
|
is_external = (file->no_write == 0 &&
|
||||||
|
file->sections[0].block == 0xfffffffe);
|
||||||
|
|
||||||
|
section_size = iso_stream_get_size(file->stream);
|
||||||
for (extent = 0; extent < file->nsections - 1; ++extent) {
|
for (extent = 0; extent < file->nsections - 1; ++extent) {
|
||||||
file->sections[extent].block = t->curblock + extent *
|
file->sections[extent].block = t->filesrc_blocks + extent *
|
||||||
(ISO_EXTENT_SIZE / BLOCK_SIZE);
|
(ISO_EXTENT_SIZE / BLOCK_SIZE);
|
||||||
file->sections[extent].size = ISO_EXTENT_SIZE;
|
file->sections[extent].size = ISO_EXTENT_SIZE;
|
||||||
section_size -= (off_t) ISO_EXTENT_SIZE;
|
section_size -= (off_t) ISO_EXTENT_SIZE;
|
||||||
@ -275,14 +290,29 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
* final section
|
* final section
|
||||||
*/
|
*/
|
||||||
if (section_size <= 0) {
|
if (section_size <= 0) {
|
||||||
file->sections[extent].block = t->empty_file_block;
|
/* Will become t->empty_file_block
|
||||||
|
in filesrc_writer_compute_data_blocks()
|
||||||
|
Special use of 0xffffffe0 to 0xffffffff is covered by
|
||||||
|
mspad_writer which enforces a minimum start of filesrc at
|
||||||
|
block 0x00000020.
|
||||||
|
*/
|
||||||
|
file->sections[extent].block = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
file->sections[extent].block =
|
file->sections[extent].block =
|
||||||
t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
|
t->filesrc_blocks + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
file->sections[extent].size = (uint32_t)section_size;
|
file->sections[extent].size = (uint32_t)section_size;
|
||||||
|
|
||||||
t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
/* 0xfffffffe in emerging image means that this is an external
|
||||||
|
partition. Others will take care of the content data.
|
||||||
|
*/
|
||||||
|
if (is_external) {
|
||||||
|
file->sections[0].block = 0xfffffffe;
|
||||||
|
file->no_write = 1; /* Ban for filesrc_writer */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->filesrc_blocks += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the list is only needed by this writer, store locally */
|
/* the list is only needed by this writer, store locally */
|
||||||
@ -290,6 +320,46 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
Ecma119Image *t;
|
||||||
|
int extent = 0;
|
||||||
|
size_t i;
|
||||||
|
IsoFileSrc *file;
|
||||||
|
IsoFileSrc **filelist;
|
||||||
|
|
||||||
|
if (writer == NULL) {
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
t = writer->target;
|
||||||
|
filelist = (IsoFileSrc **) writer->data;
|
||||||
|
|
||||||
|
/* >>> HFS: need to align to allocation block size */;
|
||||||
|
/* >>> HFS: ??? how to handle multi-extent files ? */;
|
||||||
|
|
||||||
|
t->filesrc_start = t->curblock;
|
||||||
|
|
||||||
|
/* Give all extent addresses their final absolute value */
|
||||||
|
i = 0;
|
||||||
|
while ((file = filelist[i++]) != NULL) {
|
||||||
|
|
||||||
|
/* Skip external partitions */
|
||||||
|
if (file->no_write)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (extent = 0; extent < file->nsections; ++extent) {
|
||||||
|
if (file->sections[extent].block == 0xffffffff)
|
||||||
|
file->sections[extent].block = t->empty_file_block;
|
||||||
|
else
|
||||||
|
file->sections[extent].block += t->curblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t->curblock += t->filesrc_blocks;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int filesrc_writer_write_vol_desc(IsoImageWriter *writer)
|
int filesrc_writer_write_vol_desc(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
@ -332,26 +402,247 @@ int filesrc_make_md5(Ecma119Image *t, IsoFileSrc *file, char md5[16], int flag)
|
|||||||
return iso_stream_make_md5(file->stream, md5, 0);
|
return iso_stream_make_md5(file->stream, md5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
/* name must be NULL or offer at least PATH_MAX characters.
|
||||||
int filesrc_writer_write_data(IsoImageWriter *writer)
|
buffer must be NULL or offer at least BLOCK_SIZE characters.
|
||||||
|
*/
|
||||||
|
int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
|
||||||
|
char *name, char *buffer, int flag)
|
||||||
{
|
{
|
||||||
int res, ret, was_error;
|
int res, ret, was_error;
|
||||||
size_t i, b;
|
char *name_data = NULL;
|
||||||
Ecma119Image *t = NULL;
|
char *buffer_data = NULL;
|
||||||
IsoFileSrc *file;
|
size_t b;
|
||||||
IsoFileSrc **filelist;
|
|
||||||
char *name = NULL;
|
|
||||||
char *buffer = NULL;
|
|
||||||
off_t file_size;
|
off_t file_size;
|
||||||
uint32_t nblocks;
|
uint32_t nblocks;
|
||||||
void *ctx= NULL;
|
void *ctx= NULL;
|
||||||
char md5[16], pre_md5[16];
|
char md5[16], pre_md5[16];
|
||||||
int pre_md5_valid = 0;
|
int pre_md5_valid = 0;
|
||||||
IsoStream *stream, *inp;
|
IsoStream *stream, *inp;
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
#ifdef Libisofs_with_libjtE
|
||||||
int jte_begun = 0;
|
int jte_begun = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (name == NULL) {
|
||||||
|
LIBISO_ALLOC_MEM(name_data, char, PATH_MAX);
|
||||||
|
name = name_data;
|
||||||
|
}
|
||||||
|
if (buffer == NULL) {
|
||||||
|
LIBISO_ALLOC_MEM(buffer_data, char, BLOCK_SIZE);
|
||||||
|
buffer = buffer_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
was_error = 0;
|
||||||
|
file_size = iso_file_src_get_size(file);
|
||||||
|
nblocks = DIV_UP(file_size, BLOCK_SIZE);
|
||||||
|
pre_md5_valid = 0;
|
||||||
|
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
|
||||||
|
/* Obtain an MD5 of content by a first read pass */
|
||||||
|
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
|
||||||
|
}
|
||||||
|
res = filesrc_open(file);
|
||||||
|
|
||||||
|
/* Get file name from end of filter chain */
|
||||||
|
for (stream = file->stream; ; stream = inp) {
|
||||||
|
inp = iso_stream_get_input_stream(stream, 0);
|
||||||
|
if (inp == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iso_stream_get_file_name(stream, name);
|
||||||
|
if (res < 0) {
|
||||||
|
/*
|
||||||
|
* UPS, very ugly error, the best we can do is just to write
|
||||||
|
* 0's to image
|
||||||
|
*/
|
||||||
|
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
||||||
|
was_error = 1;
|
||||||
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
|
||||||
|
"File \"%s\" can't be opened. Filling with 0s.", name);
|
||||||
|
if (res < 0) {
|
||||||
|
ret = res; /* aborted due to error severity */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
|
for (b = 0; b < nblocks; ++b) {
|
||||||
|
res = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
if (res < 0) {
|
||||||
|
/* ko, writer error, we need to go out! */
|
||||||
|
ret = res;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
goto ex;
|
||||||
|
} else if (res > 1) {
|
||||||
|
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
||||||
|
was_error = 1;
|
||||||
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
||||||
|
"Size of file \"%s\" has changed. It will be %s", name,
|
||||||
|
(res == 2 ? "truncated" : "padded with 0's"));
|
||||||
|
if (res < 0) {
|
||||||
|
filesrc_close(file);
|
||||||
|
ret = res; /* aborted due to error severity */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef LIBISOFS_VERBOSE_DEBUG
|
||||||
|
else {
|
||||||
|
iso_msg_debug(t->image->id, "Writing file %s", name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* >>> HFS: need to align to allocation block size */;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
|
if (t->libjte_handle != NULL) {
|
||||||
|
res = libjte_begin_data_file(t->libjte_handle, name,
|
||||||
|
BLOCK_SIZE, file_size);
|
||||||
|
if (res <= 0) {
|
||||||
|
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||||
|
ISO_LIBJTE_FILE_FAILED, 0);
|
||||||
|
if (res < 0) {
|
||||||
|
filesrc_close(file);
|
||||||
|
ret = ISO_LIBJTE_FILE_FAILED;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jte_begun = 1;
|
||||||
|
}
|
||||||
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
if (file->checksum_index > 0) {
|
||||||
|
/* initialize file checksum */
|
||||||
|
res = iso_md5_start(&ctx);
|
||||||
|
if (res <= 0)
|
||||||
|
file->checksum_index = 0;
|
||||||
|
}
|
||||||
|
/* write file contents to image */
|
||||||
|
for (b = 0; b < nblocks; ++b) {
|
||||||
|
int wres;
|
||||||
|
res = filesrc_read(file, buffer, BLOCK_SIZE);
|
||||||
|
if (res < 0) {
|
||||||
|
/* read error */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wres = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
if (wres < 0) {
|
||||||
|
/* ko, writer error, we need to go out! */
|
||||||
|
filesrc_close(file);
|
||||||
|
ret = wres;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (file->checksum_index > 0) {
|
||||||
|
/* Add to file checksum */
|
||||||
|
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
||||||
|
res = BLOCK_SIZE;
|
||||||
|
else
|
||||||
|
res = file_size - b * BLOCK_SIZE;
|
||||||
|
res = iso_md5_compute(ctx, buffer, res);
|
||||||
|
if (res <= 0)
|
||||||
|
file->checksum_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filesrc_close(file);
|
||||||
|
|
||||||
|
if (b < nblocks) {
|
||||||
|
/* premature end of file, due to error or eof */
|
||||||
|
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
||||||
|
was_error = 1;
|
||||||
|
if (res < 0) {
|
||||||
|
/* error */
|
||||||
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
|
||||||
|
"Read error in file %s.", name);
|
||||||
|
} else {
|
||||||
|
/* eof */
|
||||||
|
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
||||||
|
"Premature end of file %s.", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
ret = res; /* aborted due error severity */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill with 0s */
|
||||||
|
iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
||||||
|
"Filling with 0");
|
||||||
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
|
while (b++ < nblocks) {
|
||||||
|
res = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
if (res < 0) {
|
||||||
|
/* ko, writer error, we need to go out! */
|
||||||
|
ret = res;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (file->checksum_index > 0) {
|
||||||
|
/* Add to file checksum */
|
||||||
|
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
||||||
|
res = BLOCK_SIZE;
|
||||||
|
else
|
||||||
|
res = file_size - b * BLOCK_SIZE;
|
||||||
|
res = iso_md5_compute(ctx, buffer, res);
|
||||||
|
if (res <= 0)
|
||||||
|
file->checksum_index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (file->checksum_index > 0 &&
|
||||||
|
file->checksum_index <= t->checksum_idx_counter) {
|
||||||
|
/* Obtain checksum and dispose checksum context */
|
||||||
|
res = iso_md5_end(&ctx, md5);
|
||||||
|
if (res <= 0)
|
||||||
|
file->checksum_index = 0;
|
||||||
|
if ((t->md5_file_checksums & 2) && pre_md5_valid > 0 &&
|
||||||
|
!was_error) {
|
||||||
|
if (! iso_md5_match(md5, pre_md5)) {
|
||||||
|
/* Issue MISHAP event */
|
||||||
|
iso_report_errfile(name, ISO_MD5_STREAM_CHANGE, 0, 0);
|
||||||
|
was_error = 1;
|
||||||
|
res = iso_msg_submit(t->image->id, ISO_MD5_STREAM_CHANGE,0,
|
||||||
|
"Content of file '%s' changed while it was written into the image.",
|
||||||
|
name);
|
||||||
|
if (res < 0) {
|
||||||
|
ret = res; /* aborted due to error severity */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Write md5 into checksum buffer at file->checksum_index */
|
||||||
|
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (ctx != NULL) /* avoid any memory leak */
|
||||||
|
iso_md5_end(&ctx, md5);
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_libjtE
|
||||||
|
if (jte_begun) {
|
||||||
|
res = libjte_end_data_file(t->libjte_handle);
|
||||||
|
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||||
|
ISO_LIBJTE_END_FAILED, 0);
|
||||||
|
if (res <= 0 && ret >= 0)
|
||||||
|
ret = ISO_LIBJTE_FILE_FAILED;
|
||||||
|
}
|
||||||
|
#endif /* Libisofs_with_libjtE */
|
||||||
|
|
||||||
|
LIBISO_FREE_MEM(buffer_data);
|
||||||
|
LIBISO_FREE_MEM(name_data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t i;
|
||||||
|
Ecma119Image *t = NULL;
|
||||||
|
IsoFileSrc *file;
|
||||||
|
IsoFileSrc **filelist;
|
||||||
|
char *name = NULL;
|
||||||
|
char *buffer = NULL;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
ret = ISO_ASSERT_FAILURE; goto ex;
|
ret = ISO_ASSERT_FAILURE; goto ex;
|
||||||
}
|
}
|
||||||
@ -375,216 +666,28 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((file = filelist[i++]) != NULL) {
|
while ((file = filelist[i++]) != NULL) {
|
||||||
was_error = 0;
|
if (file->no_write) {
|
||||||
file_size = iso_file_src_get_size(file);
|
/* Do not write external partitions */
|
||||||
nblocks = DIV_UP(file_size, BLOCK_SIZE);
|
iso_msg_debug(t->image->id,
|
||||||
pre_md5_valid = 0;
|
"filesrc_writer: Skipping no_write-src [%.f , %.f]",
|
||||||
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
|
(double) file->sections[0].block,
|
||||||
/* Obtain an MD5 of content by a first read pass */
|
(double) (file->sections[0].block - 1 +
|
||||||
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
|
(file->sections[0].size + 2047) / BLOCK_SIZE));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
res = filesrc_open(file);
|
ret = iso_filesrc_write_data(t, file, name, buffer, 0);
|
||||||
|
if (ret < 0)
|
||||||
/* Get file name from end of filter chain */
|
goto ex;
|
||||||
for (stream = file->stream; ; stream = inp) {
|
|
||||||
inp = iso_stream_get_input_stream(stream, 0);
|
|
||||||
if (inp == NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
iso_stream_get_file_name(stream, name);
|
|
||||||
if (res < 0) {
|
|
||||||
/*
|
|
||||||
* UPS, very ugly error, the best we can do is just to write
|
|
||||||
* 0's to image
|
|
||||||
*/
|
|
||||||
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
|
||||||
was_error = 1;
|
|
||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
|
|
||||||
"File \"%s\" can't be opened. Filling with 0s.", name);
|
|
||||||
if (res < 0) {
|
|
||||||
ret = res; /* aborted due to error severity */
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
|
||||||
for (b = 0; b < nblocks; ++b) {
|
|
||||||
res = iso_write(t, buffer, BLOCK_SIZE);
|
|
||||||
if (res < 0) {
|
|
||||||
/* ko, writer error, we need to go out! */
|
|
||||||
ret = res;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
} else if (res > 1) {
|
|
||||||
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
|
||||||
was_error = 1;
|
|
||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
|
||||||
"Size of file \"%s\" has changed. It will be %s", name,
|
|
||||||
(res == 2 ? "truncated" : "padded with 0's"));
|
|
||||||
if (res < 0) {
|
|
||||||
filesrc_close(file);
|
|
||||||
ret = res; /* aborted due to error severity */
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef LIBISOFS_VERBOSE_DEBUG
|
|
||||||
else {
|
|
||||||
iso_msg_debug(t->image->id, "Writing file %s", name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
|
||||||
if (t->libjte_handle != NULL) {
|
|
||||||
res = libjte_begin_data_file(t->libjte_handle, name,
|
|
||||||
BLOCK_SIZE, file_size);
|
|
||||||
if (res <= 0) {
|
|
||||||
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
|
||||||
ISO_LIBJTE_FILE_FAILED, 0);
|
|
||||||
if (res < 0) {
|
|
||||||
filesrc_close(file);
|
|
||||||
ret = ISO_LIBJTE_FILE_FAILED;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jte_begun = 1;
|
|
||||||
}
|
|
||||||
#endif /* Libisofs_with_libjtE */
|
|
||||||
|
|
||||||
if (file->checksum_index > 0) {
|
|
||||||
/* initialize file checksum */
|
|
||||||
res = iso_md5_start(&ctx);
|
|
||||||
if (res <= 0)
|
|
||||||
file->checksum_index = 0;
|
|
||||||
}
|
|
||||||
/* write file contents to image */
|
|
||||||
for (b = 0; b < nblocks; ++b) {
|
|
||||||
int wres;
|
|
||||||
res = filesrc_read(file, buffer, BLOCK_SIZE);
|
|
||||||
if (res < 0) {
|
|
||||||
/* read error */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wres = iso_write(t, buffer, BLOCK_SIZE);
|
|
||||||
if (wres < 0) {
|
|
||||||
/* ko, writer error, we need to go out! */
|
|
||||||
filesrc_close(file);
|
|
||||||
ret = wres;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
if (file->checksum_index > 0) {
|
|
||||||
/* Add to file checksum */
|
|
||||||
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
|
||||||
res = BLOCK_SIZE;
|
|
||||||
else
|
|
||||||
res = file_size - b * BLOCK_SIZE;
|
|
||||||
res = iso_md5_compute(ctx, buffer, res);
|
|
||||||
if (res <= 0)
|
|
||||||
file->checksum_index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filesrc_close(file);
|
|
||||||
|
|
||||||
if (b < nblocks) {
|
|
||||||
/* premature end of file, due to error or eof */
|
|
||||||
iso_report_errfile(name, ISO_FILE_CANT_WRITE, 0, 0);
|
|
||||||
was_error = 1;
|
|
||||||
if (res < 0) {
|
|
||||||
/* error */
|
|
||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, res,
|
|
||||||
"Read error in file %s.", name);
|
|
||||||
} else {
|
|
||||||
/* eof */
|
|
||||||
res = iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
|
||||||
"Premature end of file %s.", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res < 0) {
|
|
||||||
ret = res; /* aborted due error severity */
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill with 0s */
|
|
||||||
iso_msg_submit(t->image->id, ISO_FILE_CANT_WRITE, 0,
|
|
||||||
"Filling with 0");
|
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
|
||||||
while (b++ < nblocks) {
|
|
||||||
res = iso_write(t, buffer, BLOCK_SIZE);
|
|
||||||
if (res < 0) {
|
|
||||||
/* ko, writer error, we need to go out! */
|
|
||||||
ret = res;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
if (file->checksum_index > 0) {
|
|
||||||
/* Add to file checksum */
|
|
||||||
if (file_size - b * BLOCK_SIZE > BLOCK_SIZE)
|
|
||||||
res = BLOCK_SIZE;
|
|
||||||
else
|
|
||||||
res = file_size - b * BLOCK_SIZE;
|
|
||||||
res = iso_md5_compute(ctx, buffer, res);
|
|
||||||
if (res <= 0)
|
|
||||||
file->checksum_index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (file->checksum_index > 0 &&
|
|
||||||
file->checksum_index <= t->checksum_idx_counter) {
|
|
||||||
/* Obtain checksum and dispose checksum context */
|
|
||||||
res = iso_md5_end(&ctx, md5);
|
|
||||||
if (res <= 0)
|
|
||||||
file->checksum_index = 0;
|
|
||||||
if ((t->md5_file_checksums & 2) && pre_md5_valid > 0 &&
|
|
||||||
!was_error) {
|
|
||||||
if (! iso_md5_match(md5, pre_md5)) {
|
|
||||||
/* Issue MISHAP event */
|
|
||||||
iso_report_errfile(name, ISO_MD5_STREAM_CHANGE, 0, 0);
|
|
||||||
was_error = 1;
|
|
||||||
res = iso_msg_submit(t->image->id, ISO_MD5_STREAM_CHANGE,0,
|
|
||||||
"Content of file '%s' changed while it was written into the image.",
|
|
||||||
name);
|
|
||||||
if (res < 0) {
|
|
||||||
ret = res; /* aborted due to error severity */
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Write md5 into checksum buffer at file->checksum_index */
|
|
||||||
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
|
||||||
if (t->libjte_handle != NULL) {
|
|
||||||
res = libjte_end_data_file(t->libjte_handle);
|
|
||||||
if (res <= 0) {
|
|
||||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
|
||||||
ISO_LIBJTE_FILE_FAILED, 0);
|
|
||||||
ret = ISO_LIBJTE_FILE_FAILED;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
jte_begun = 0;
|
|
||||||
}
|
|
||||||
#endif /* Libisofs_with_libjtE */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
if (ctx != NULL) /* avoid any memory leak */
|
|
||||||
iso_md5_end(&ctx, md5);
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_libjtE
|
|
||||||
if (jte_begun && t != NULL) {
|
|
||||||
libjte_end_data_file(t->libjte_handle);
|
|
||||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
|
||||||
ISO_LIBJTE_END_FAILED, 0);
|
|
||||||
}
|
|
||||||
#endif /* Libisofs_with_libjtE */
|
|
||||||
|
|
||||||
LIBISO_FREE_MEM(buffer);
|
LIBISO_FREE_MEM(buffer);
|
||||||
LIBISO_FREE_MEM(name);
|
LIBISO_FREE_MEM(name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int filesrc_writer_free_data(IsoImageWriter *writer)
|
int filesrc_writer_free_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* 2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -21,12 +22,33 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Abstraction of data file content in the emerging image.
|
||||||
|
*/
|
||||||
struct Iso_File_Src
|
struct Iso_File_Src
|
||||||
{
|
{
|
||||||
unsigned int prev_img :1; /**< if the file comes from a previous image */
|
/* This marks an IsoFileSrc which shall only expose its extent addresses
|
||||||
|
and sizes but shall not be counted or written by filesrc_writer.
|
||||||
|
*/
|
||||||
|
unsigned int no_write :1;
|
||||||
|
|
||||||
unsigned int checksum_index :31;
|
unsigned int checksum_index :31;
|
||||||
|
|
||||||
/** File Sections of the file in the image */
|
/** File Sections of the file in the image */
|
||||||
|
/* Special sections[0].block values while they are relative
|
||||||
|
before filesrc_writer_compute_data_blocks().
|
||||||
|
Valid only with .no_write == 0:
|
||||||
|
0xfffffffe This Iso_File_Src is claimed as external partition.
|
||||||
|
Others will take care of the content data.
|
||||||
|
filesrc_writer shall neither count nor write it.
|
||||||
|
At write_data time it is already converted to
|
||||||
|
a fileadress between Ecma119Image.ms_block and
|
||||||
|
Ecma119Image.filesrc_start - 1.
|
||||||
|
0xffffffff This is the block to which empty files shall point.
|
||||||
|
Normal data files have relative addresses from 0 to 0xffffffdf.
|
||||||
|
They cannot be higher, because mspad_writer forces the absolute
|
||||||
|
filesrc addresses to start at least at 0x20.
|
||||||
|
*/
|
||||||
struct iso_file_section *sections;
|
struct iso_file_section *sections;
|
||||||
int nsections;
|
int nsections;
|
||||||
|
|
||||||
@ -93,4 +115,21 @@ off_t iso_file_src_get_size(IsoFileSrc *file);
|
|||||||
*/
|
*/
|
||||||
int iso_file_src_writer_create(Ecma119Image *target);
|
int iso_file_src_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine number of filesrc blocks in the image and compute extent addresses
|
||||||
|
* relative to start of the file source writer area.
|
||||||
|
* filesrc_writer_compute_data_blocks() later makes them absolute.
|
||||||
|
*/
|
||||||
|
int filesrc_writer_pre_compute(IsoImageWriter *writer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the content of file into the output stream of t.
|
||||||
|
* name must be NULL or offer at least PATH_MAX characters of storage.
|
||||||
|
* buffer must be NULL or offer at least BLOCK_SIZE characters of storage.
|
||||||
|
* flag is not used yet, submit 0.
|
||||||
|
*/
|
||||||
|
int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
|
||||||
|
char *name, char *buffer, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_FILESRC_H_*/
|
#endif /*LIBISO_FILESRC_H_*/
|
||||||
|
@ -35,6 +35,22 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Enable this and write the correct absolute path into the include statement
|
||||||
|
below in order to test the pending contribution to syslinux:
|
||||||
|
http://www.syslinux.org/archives/2013-March/019755.html
|
||||||
|
|
||||||
|
# def ine Libisofs_syslinux_tesT 1
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifdef Libisofs_syslinux_tesT
|
||||||
|
#define Isolinux_rockridge_in_libisofS 1
|
||||||
|
#include "/reiser/syslinux/core/fs/iso9660/susp_rr.c"
|
||||||
|
/*
|
||||||
|
# inc lude "/home/thomas/projekte/cdrskin_dir/libisoburn-develop/test/susp_rr.c"
|
||||||
|
*/
|
||||||
|
#endif /* Libisofs_syslinux_tesT */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for image reading.
|
* Options for image reading.
|
||||||
* There are four kind of options:
|
* There are four kind of options:
|
||||||
@ -241,6 +257,10 @@ typedef struct
|
|||||||
char *copyright_file_id;
|
char *copyright_file_id;
|
||||||
char *abstract_file_id;
|
char *abstract_file_id;
|
||||||
char *biblio_file_id;
|
char *biblio_file_id;
|
||||||
|
char *creation_time;
|
||||||
|
char *modification_time;
|
||||||
|
char *expiration_time;
|
||||||
|
char *effective_time;
|
||||||
|
|
||||||
/* extension information */
|
/* extension information */
|
||||||
|
|
||||||
@ -310,6 +330,30 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
int px_ino_status;
|
int px_ino_status;
|
||||||
|
|
||||||
|
/* Which Rock Ridge error messages already have occured
|
||||||
|
bit0= Invalid PX entry
|
||||||
|
bit1= Invalid TF entry
|
||||||
|
bit2= New NM entry found without previous CONTINUE flag
|
||||||
|
bit3= Invalid NM entry
|
||||||
|
bit4= New SL entry found without previous CONTINUE flag
|
||||||
|
bit5= Invalid SL entry
|
||||||
|
bit6= Invalid SL entry, no child location
|
||||||
|
bit7= Invalid PN entry
|
||||||
|
bit8= Sparse files not supported
|
||||||
|
bit9= SP entry found in a directory entry other than '.' entry of root
|
||||||
|
bit10= ER entry found in a directory entry other than '.' entry of root
|
||||||
|
bit11= Invalid AA entry
|
||||||
|
bit12= Invalid AL entry
|
||||||
|
bit13= Invalid ZF entry
|
||||||
|
bit14= Rock Ridge PX entry is not present or invalid
|
||||||
|
bit15= Incomplete NM
|
||||||
|
bit16= Incomplete SL
|
||||||
|
bit17= Charset conversion error
|
||||||
|
bit18= Link without destination
|
||||||
|
*/
|
||||||
|
int rr_err_reported;
|
||||||
|
int rr_err_repeated;
|
||||||
|
|
||||||
} _ImageFsData;
|
} _ImageFsData;
|
||||||
|
|
||||||
typedef struct image_fs_data ImageFileSourceData;
|
typedef struct image_fs_data ImageFileSourceData;
|
||||||
@ -430,6 +474,8 @@ int ifs_lstat(IsoFileSource *src, struct stat *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = src->data;
|
data = src->data;
|
||||||
|
if (data == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
*info = data->info;
|
*info = data->info;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1227,6 +1273,30 @@ char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_rr_msg_submit(_ImageFsData *fsdata, int rr_err_bit,
|
||||||
|
int errcode, int causedby, const char *msg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((fsdata->rr_err_reported & (1 << rr_err_bit)) &&
|
||||||
|
(fsdata->rr_err_repeated & (1 << rr_err_bit))) {
|
||||||
|
if (iso_msg_is_abort(errcode))
|
||||||
|
return ISO_CANCELED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (fsdata->rr_err_reported & (1 << rr_err_bit)) {
|
||||||
|
ret = iso_msg_submit(fsdata->msgid, errcode, causedby,
|
||||||
|
"MORE THAN ONCE : %s", msg);
|
||||||
|
fsdata->rr_err_repeated |= (1 << rr_err_bit);
|
||||||
|
} else {
|
||||||
|
ret = iso_msg_submit(fsdata->msgid, errcode, causedby, "%s", msg);
|
||||||
|
fsdata->rr_err_reported |= (1 << rr_err_bit);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param src
|
* @param src
|
||||||
@ -1417,8 +1487,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = read_rr_PX(sue, &atts);
|
ret = read_rr_PX(sue, &atts);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 0, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid PX entry");
|
"Invalid PX entry");
|
||||||
fsdata->px_ino_status |= 8;
|
fsdata->px_ino_status |= 8;
|
||||||
} if (ret == 2) {
|
} if (ret == 2) {
|
||||||
if (fsdata->inode_counter < atts.st_ino)
|
if (fsdata->inode_counter < atts.st_ino)
|
||||||
@ -1433,13 +1503,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = read_rr_TF(sue, &atts);
|
ret = read_rr_TF(sue, &atts);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 1, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid TF entry");
|
"Invalid TF entry");
|
||||||
}
|
}
|
||||||
} else if (SUSP_SIG(sue, 'N', 'M')) {
|
} else if (SUSP_SIG(sue, 'N', 'M')) {
|
||||||
if (name != NULL && namecont == 0) {
|
if (name != NULL && namecont == 0) {
|
||||||
/* ups, RR standard violation */
|
/* ups, RR standard violation */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0,
|
ret = iso_rr_msg_submit(fsdata, 2, ISO_WRONG_RR_WARN, 0,
|
||||||
"New NM entry found without previous"
|
"New NM entry found without previous"
|
||||||
"CONTINUE flag. Ignored");
|
"CONTINUE flag. Ignored");
|
||||||
continue;
|
continue;
|
||||||
@ -1447,13 +1517,52 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = read_rr_NM(sue, &name, &namecont);
|
ret = read_rr_NM(sue, &name, &namecont);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 3, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid NM entry");
|
"Invalid NM entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_syslinux_tesT
|
||||||
|
|
||||||
|
if (name != NULL && !namecont) {
|
||||||
|
struct device syslinux_dev;
|
||||||
|
struct iso_sb_info syslinux_sbi;
|
||||||
|
struct fs_info syslinux_fsi;
|
||||||
|
char *syslinux_name = NULL;
|
||||||
|
int syslinux_name_len;
|
||||||
|
|
||||||
|
syslinux_dev.src = fsdata->src;
|
||||||
|
memset(&(syslinux_sbi.root), 0, 256);
|
||||||
|
syslinux_sbi.do_rr = 1;
|
||||||
|
syslinux_sbi.susp_skip = 0;
|
||||||
|
syslinux_fsi.fs_dev = &syslinux_dev;
|
||||||
|
syslinux_fsi.fs_info = &syslinux_sbi;
|
||||||
|
ret = susp_rr_get_nm(&syslinux_fsi, (char *) record,
|
||||||
|
&syslinux_name, &syslinux_name_len);
|
||||||
|
if (ret == 1) {
|
||||||
|
if (name == NULL || syslinux_name == NULL)
|
||||||
|
fprintf(stderr, "################ Hoppla. NULL\n");
|
||||||
|
else if(strcmp(syslinux_name, name) != 0)
|
||||||
|
fprintf(stderr,
|
||||||
|
"################ libisofs '%s' != '%s' susp_rr_get_nm()\n",
|
||||||
|
name, syslinux_name);
|
||||||
|
} else if (ret == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"################ '%s' not found by susp_rr_get_nm()\n", name);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "################ 'susp_rr_get_nm() returned error\n");
|
||||||
|
}
|
||||||
|
if (syslinux_name != NULL)
|
||||||
|
free(syslinux_name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_syslinux_tesT */
|
||||||
|
|
||||||
|
|
||||||
} else if (SUSP_SIG(sue, 'S', 'L')) {
|
} else if (SUSP_SIG(sue, 'S', 'L')) {
|
||||||
if (linkdest != NULL && linkdestcont == 0) {
|
if (linkdest != NULL && linkdestcont == 0) {
|
||||||
/* ups, RR standard violation */
|
/* ups, RR standard violation */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, 0,
|
ret = iso_rr_msg_submit(fsdata, 4, ISO_WRONG_RR_WARN, 0,
|
||||||
"New SL entry found without previous"
|
"New SL entry found without previous"
|
||||||
"CONTINUE flag. Ignored");
|
"CONTINUE flag. Ignored");
|
||||||
continue;
|
continue;
|
||||||
@ -1461,8 +1570,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = read_rr_SL(sue, &linkdest, &linkdestcont);
|
ret = read_rr_SL(sue, &linkdest, &linkdestcont);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 5, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid SL entry");
|
"Invalid SL entry");
|
||||||
}
|
}
|
||||||
} else if (SUSP_SIG(sue, 'R', 'E')) {
|
} else if (SUSP_SIG(sue, 'R', 'E')) {
|
||||||
/*
|
/*
|
||||||
@ -1482,7 +1591,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
*/
|
*/
|
||||||
relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL);
|
relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL);
|
||||||
if (relocated_dir == 0) {
|
if (relocated_dir == 0) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
|
||||||
"Invalid SL entry, no child location");
|
"Invalid SL entry, no child location");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1490,12 +1599,12 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = read_rr_PN(sue, &atts);
|
ret = read_rr_PN(sue, &atts);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 7, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid PN entry");
|
"Invalid PN entry");
|
||||||
}
|
}
|
||||||
} else if (SUSP_SIG(sue, 'S', 'F')) {
|
} else if (SUSP_SIG(sue, 'S', 'F')) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 8, ISO_UNSUPPORTED_RR, 0,
|
||||||
"Sparse files not supported.");
|
"Sparse files not supported.");
|
||||||
break;
|
break;
|
||||||
} else if (SUSP_SIG(sue, 'R', 'R')) {
|
} else if (SUSP_SIG(sue, 'R', 'R')) {
|
||||||
/* This was an optional flag byte in RRIP 1.09 which told the
|
/* This was an optional flag byte in RRIP 1.09 which told the
|
||||||
@ -1510,7 +1619,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
*/
|
*/
|
||||||
if (!(flag & 1)) {
|
if (!(flag & 1)) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 9, ISO_WRONG_RR, 0,
|
||||||
"SP entry found in a directory entry other "
|
"SP entry found in a directory entry other "
|
||||||
"than '.' entry of root node");
|
"than '.' entry of root node");
|
||||||
}
|
}
|
||||||
@ -1522,7 +1631,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
*/
|
*/
|
||||||
if (!(flag & 1)) {
|
if (!(flag & 1)) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 10, ISO_WRONG_RR, 0,
|
||||||
"ER entry found in a directory entry other "
|
"ER entry found in a directory entry other "
|
||||||
"than '.' entry of root node");
|
"than '.' entry of root node");
|
||||||
}
|
}
|
||||||
@ -1537,8 +1646,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
&prev_field, &aa_done, 0);
|
&prev_field, &aa_done, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 11, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid AA entry");
|
"Invalid AA entry");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1548,8 +1657,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
&prev_field, &aa_done, 0);
|
&prev_field, &aa_done, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 12, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid AL entry");
|
"Invalid AL entry");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1561,7 +1670,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
&zisofs_bsl2, &zisofs_usize, 0);
|
&zisofs_bsl2, &zisofs_usize, 0);
|
||||||
if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') {
|
if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') {
|
||||||
/* notify and continue */
|
/* notify and continue */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR_WARN, ret,
|
ret = iso_rr_msg_submit(fsdata, 13, ISO_WRONG_RR_WARN, ret,
|
||||||
"Invalid ZF entry");
|
"Invalid ZF entry");
|
||||||
zisofs_hs4 = 0;
|
zisofs_hs4 = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -1587,17 +1696,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
/* error was already submitted above */
|
/* error was already submitted above */
|
||||||
iso_msg_debug(fsdata->msgid, "Error parsing RR entries");
|
iso_msg_debug(fsdata->msgid, "Error parsing RR entries");
|
||||||
} else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) {
|
} else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0, "Mandatory "
|
ret = iso_rr_msg_submit(fsdata, 14, ISO_WRONG_RR, 0, "Mandatory "
|
||||||
"Rock Ridge PX entry is not present or it "
|
"Rock Ridge PX entry is not present or it "
|
||||||
"contains invalid values.");
|
"contains invalid values.");
|
||||||
} else {
|
} else {
|
||||||
/* ensure both name and link dest are finished */
|
/* ensure both name and link dest are finished */
|
||||||
if (namecont != 0) {
|
if (namecont != 0) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 15, ISO_WRONG_RR, 0,
|
||||||
"Incomplete RR name, last NM entry continues");
|
"Incomplete Rock Ridge name, last NM entry continues");
|
||||||
}
|
}
|
||||||
if (linkdestcont != 0) {
|
if (linkdestcont != 0) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 16, ISO_WRONG_RR, 0,
|
||||||
"Incomplete link destination, last SL entry continues");
|
"Incomplete link destination, last SL entry continues");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1611,6 +1720,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
|
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
|
||||||
&cs_value_length, &cs_value, 0);
|
&cs_value_length, &cs_value, 0);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
|
LIBISO_FREE_MEM(msg);
|
||||||
LIBISO_ALLOC_MEM(msg, char, 160);
|
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||||
if (fsdata->auto_input_charset & 1) {
|
if (fsdata->auto_input_charset & 1) {
|
||||||
if (fsdata->input_charset != NULL)
|
if (fsdata->input_charset != NULL)
|
||||||
@ -1638,10 +1748,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
&newname);
|
&newname);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* its just a hint message */
|
/* its just a hint message */
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET,
|
LIBISO_FREE_MEM(msg);
|
||||||
ret, "Charset conversion error. Cannot "
|
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||||
"convert from %s to %s",
|
sprintf(msg,
|
||||||
|
"Charset conversion error. Cannot convert from %.40s to %.40s",
|
||||||
fsdata->input_charset, fsdata->local_charset);
|
fsdata->input_charset, fsdata->local_charset);
|
||||||
|
ret = iso_rr_msg_submit(fsdata, 17, ISO_FILENAME_WRONG_CHARSET,
|
||||||
|
ret, msg);
|
||||||
free(newname);
|
free(newname);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
@ -1660,10 +1773,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
ret = strconv(linkdest, fsdata->input_charset,
|
ret = strconv(linkdest, fsdata->input_charset,
|
||||||
fsdata->local_charset, &newlinkdest);
|
fsdata->local_charset, &newlinkdest);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_FILENAME_WRONG_CHARSET,
|
LIBISO_FREE_MEM(msg);
|
||||||
ret, "Charset conversion error. Cannot "
|
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||||
"convert from %s to %s",
|
sprintf(msg,
|
||||||
|
"Charset conversion error. Cannot convert from %.40s to %.40s",
|
||||||
fsdata->input_charset, fsdata->local_charset);
|
fsdata->input_charset, fsdata->local_charset);
|
||||||
|
ret = iso_rr_msg_submit(fsdata, 17, ISO_FILENAME_WRONG_CHARSET,
|
||||||
|
ret, msg);
|
||||||
free(newlinkdest);
|
free(newlinkdest);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
free(name);
|
||||||
@ -1786,8 +1902,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
|||||||
|
|
||||||
/* TODO #00014 : more sanity checks to ensure dir record info is valid */
|
/* TODO #00014 : more sanity checks to ensure dir record info is valid */
|
||||||
if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) {
|
if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) {
|
||||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
ret = iso_rr_msg_submit(fsdata, 18, ISO_WRONG_RR, 0,
|
||||||
"Link without destination.");
|
"Link without destination.");
|
||||||
free(name);
|
free(name);
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
@ -2087,6 +2203,10 @@ void ifs_fs_free(IsoFilesystem *fs)
|
|||||||
free(data->copyright_file_id);
|
free(data->copyright_file_id);
|
||||||
free(data->abstract_file_id);
|
free(data->abstract_file_id);
|
||||||
free(data->biblio_file_id);
|
free(data->biblio_file_id);
|
||||||
|
free(data->creation_time);
|
||||||
|
free(data->modification_time);
|
||||||
|
free(data->expiration_time);
|
||||||
|
free(data->effective_time);
|
||||||
free(data->input_charset);
|
free(data->input_charset);
|
||||||
free(data->local_charset);
|
free(data->local_charset);
|
||||||
|
|
||||||
@ -2121,6 +2241,27 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
|||||||
/* record will be the "." directory entry for the root record */
|
/* record will be the "." directory entry for the root record */
|
||||||
record = (struct ecma119_dir_record *)buffer;
|
record = (struct ecma119_dir_record *)buffer;
|
||||||
|
|
||||||
|
#ifdef Libisofs_syslinux_tesT
|
||||||
|
|
||||||
|
{
|
||||||
|
struct device syslinux_dev;
|
||||||
|
struct iso_sb_info syslinux_sbi;
|
||||||
|
struct fs_info syslinux_fsi;
|
||||||
|
|
||||||
|
syslinux_dev.src = data->src;
|
||||||
|
memcpy(&(syslinux_sbi.root), (char *) record, 256);
|
||||||
|
syslinux_sbi.do_rr = 1;
|
||||||
|
syslinux_sbi.susp_skip = 0;
|
||||||
|
syslinux_fsi.fs_dev = &syslinux_dev;
|
||||||
|
syslinux_fsi.fs_info = &syslinux_sbi;
|
||||||
|
|
||||||
|
ret = susp_rr_check_signatures(&syslinux_fsi, 1);
|
||||||
|
fprintf(stderr, "--------- susp_rr_check_signatures == %d , syslinux_sbi.do_rr == %d\n", ret, syslinux_sbi.do_rr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_syslinux_tesT */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO #00015 : take care of CD-ROM XA discs when reading SP entry
|
* TODO #00015 : take care of CD-ROM XA discs when reading SP entry
|
||||||
* SUSP specification claims that for CD-ROM XA the SP entry
|
* SUSP specification claims that for CD-ROM XA the SP entry
|
||||||
@ -2315,7 +2456,15 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
|||||||
data->copyright_file_id[0] = 0;
|
data->copyright_file_id[0] = 0;
|
||||||
data->abstract_file_id[0] = 0;
|
data->abstract_file_id[0] = 0;
|
||||||
data->biblio_file_id[0] = 0;
|
data->biblio_file_id[0] = 0;
|
||||||
}
|
}
|
||||||
|
data->creation_time =
|
||||||
|
iso_util_strcopy_untail((char*) pvm->vol_creation_time, 17);
|
||||||
|
data->modification_time =
|
||||||
|
iso_util_strcopy_untail((char*) pvm->vol_modification_time, 17);
|
||||||
|
data->expiration_time =
|
||||||
|
iso_util_strcopy_untail((char*) pvm->vol_expiration_time, 17);
|
||||||
|
data->effective_time =
|
||||||
|
iso_util_strcopy_untail((char*) pvm->vol_effective_time, 17);
|
||||||
|
|
||||||
data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL);
|
data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL);
|
||||||
|
|
||||||
@ -2605,6 +2754,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
|||||||
data->bootblocks[i] = 0;
|
data->bootblocks[i] = 0;
|
||||||
data->inode_counter = 0;
|
data->inode_counter = 0;
|
||||||
data->px_ino_status = 0;
|
data->px_ino_status = 0;
|
||||||
|
data->rr_err_reported = 0;
|
||||||
|
data->rr_err_repeated = 0;
|
||||||
|
|
||||||
|
|
||||||
data->local_charset = strdup(iso_get_local_charset(0));
|
data->local_charset = strdup(iso_get_local_charset(0));
|
||||||
@ -2855,9 +3006,9 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
{
|
{
|
||||||
int ret, idx, to_copy;
|
int ret, idx, to_copy;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
IsoNode *new;
|
IsoNode *new = NULL;
|
||||||
IsoBoot *bootcat;
|
IsoBoot *bootcat;
|
||||||
char *name;
|
char *name = NULL;
|
||||||
char *dest = NULL;
|
char *dest = NULL;
|
||||||
ImageFileSourceData *data;
|
ImageFileSourceData *data;
|
||||||
_ImageFsData *fsdata;
|
_ImageFsData *fsdata;
|
||||||
@ -2885,7 +3036,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = NULL;
|
|
||||||
switch (info.st_mode & S_IFMT) {
|
switch (info.st_mode & S_IFMT) {
|
||||||
case S_IFREG:
|
case S_IFREG:
|
||||||
{
|
{
|
||||||
@ -2899,9 +3049,8 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
"More than one catalog node has been found. "
|
"More than one catalog node has been found. "
|
||||||
"We can continue, but that could lead to "
|
"We can continue, but that could lead to "
|
||||||
"problems");
|
"problems");
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
|
||||||
iso_node_unref((IsoNode*)image->bootcat->node);
|
iso_node_unref((IsoNode*)image->bootcat->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2909,9 +3058,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
* a regular file */
|
* a regular file */
|
||||||
new = calloc(1, sizeof(IsoBoot));
|
new = calloc(1, sizeof(IsoBoot));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
free(name);
|
|
||||||
goto ex;
|
|
||||||
}
|
}
|
||||||
bootcat = (IsoBoot *) new;
|
bootcat = (IsoBoot *) new;
|
||||||
bootcat->lba = data->sections[0].block;
|
bootcat->lba = data->sections[0].block;
|
||||||
@ -2922,10 +3069,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
if (bootcat->size > 0) {
|
if (bootcat->size > 0) {
|
||||||
bootcat->content = calloc(1, bootcat->size);
|
bootcat->content = calloc(1, bootcat->size);
|
||||||
if (bootcat->content == NULL) {
|
if (bootcat->content == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
free(name);
|
|
||||||
free(new);
|
|
||||||
goto ex;
|
|
||||||
}
|
}
|
||||||
to_copy = bootcat->size;
|
to_copy = bootcat->size;
|
||||||
if (bootcat->size > fsdata->catsize)
|
if (bootcat->size > fsdata->catsize)
|
||||||
@ -2942,16 +3086,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
IsoFile *file;
|
IsoFile *file;
|
||||||
|
|
||||||
ret = iso_file_source_stream_new(src, &stream);
|
ret = iso_file_source_stream_new(src, &stream);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
free(name);
|
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
|
||||||
/* take a ref to the src, as stream has taken our ref */
|
/* take a ref to the src, as stream has taken our ref */
|
||||||
iso_file_source_ref(src);
|
iso_file_source_ref(src);
|
||||||
|
|
||||||
file = calloc(1, sizeof(IsoFile));
|
file = calloc(1, sizeof(IsoFile));
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
free(name);
|
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
@ -2962,8 +3104,19 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
/*
|
/*
|
||||||
* and we set the sort weight based on the block on image, to
|
* and we set the sort weight based on the block on image, to
|
||||||
* improve performance on image modifying.
|
* improve performance on image modifying.
|
||||||
|
*
|
||||||
|
* This was too obtrusive because it occupied the highest
|
||||||
|
* possible weight ranks:
|
||||||
|
* file->sort_weight = INT_MAX - data->sections[0].block;
|
||||||
|
*
|
||||||
|
* So a try to be more nice and rely on caching with tiles
|
||||||
|
* of at least 16 blocks. This occupies a range within
|
||||||
|
* the interval of 1 to 2 exp 28 = 268,435,456.
|
||||||
|
* (Dividing each number separately saves from integer
|
||||||
|
* rollover problems.)
|
||||||
*/
|
*/
|
||||||
file->sort_weight = INT_MAX - data->sections[0].block;
|
file->sort_weight =
|
||||||
|
fsdata->nblocks / 16 - data->sections[0].block / 16 + 1;
|
||||||
|
|
||||||
file->stream = stream;
|
file->stream = stream;
|
||||||
file->node.type = LIBISO_FILE;
|
file->node.type = LIBISO_FILE;
|
||||||
@ -2975,7 +3128,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
data->block_size_log2,
|
data->block_size_log2,
|
||||||
data->uncompressed_size, 0);
|
data->uncompressed_size, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
@ -3006,7 +3158,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
|
ret = iso_msg_submit(image->id, ISO_EL_TORITO_WARN, 0,
|
||||||
"More than one ISO node has been found for the same boot image.");
|
"More than one ISO node has been found for the same boot image.");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
@ -3024,7 +3175,6 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
/* source is a directory */
|
/* source is a directory */
|
||||||
new = calloc(1, sizeof(IsoDir));
|
new = calloc(1, sizeof(IsoDir));
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
free(name);
|
|
||||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
new->type = LIBISO_DIR;
|
new->type = LIBISO_DIR;
|
||||||
@ -3040,12 +3190,10 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
|
|
||||||
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(name);
|
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
link = calloc(1, sizeof(IsoSymlink));
|
link = calloc(1, sizeof(IsoSymlink));
|
||||||
if (link == NULL) {
|
if (link == NULL) {
|
||||||
free(name);
|
|
||||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||||
}
|
}
|
||||||
link->dest = strdup(dest);
|
link->dest = strdup(dest);
|
||||||
@ -3066,8 +3214,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
IsoSpecial *special;
|
IsoSpecial *special;
|
||||||
special = calloc(1, sizeof(IsoSpecial));
|
special = calloc(1, sizeof(IsoSpecial));
|
||||||
if (special == NULL) {
|
if (special == NULL) {
|
||||||
free(name);
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
|
||||||
}
|
}
|
||||||
special->dev = info.st_rdev;
|
special->dev = info.st_rdev;
|
||||||
special->node.type = LIBISO_SPECIAL;
|
special->node.type = LIBISO_SPECIAL;
|
||||||
@ -3078,11 +3225,12 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
new->refcount = 0;
|
new->refcount = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
ret = ISO_BAD_ISO_FILETYPE; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill fields */
|
/* fill fields */
|
||||||
new->refcount++;
|
new->refcount++;
|
||||||
new->name = name;
|
new->name = name; name = NULL;
|
||||||
new->mode = info.st_mode;
|
new->mode = info.st_mode;
|
||||||
new->uid = info.st_uid;
|
new->uid = info.st_uid;
|
||||||
new->gid = info.st_gid;
|
new->gid = info.st_gid;
|
||||||
@ -3097,7 +3245,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
|
|
||||||
ret = src_aa_to_node(src, new, 0);
|
ret = src_aa_to_node(src, new, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto failure;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attach ino as xinfo if valid and no IsoStream is involved */
|
/* Attach ino as xinfo if valid and no IsoStream is involved */
|
||||||
@ -3105,18 +3253,17 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
!fsdata->make_new_ino) {
|
!fsdata->make_new_ino) {
|
||||||
ret = iso_node_set_ino(new, info.st_ino, 0);
|
ret = iso_node_set_ino(new, info.st_ino, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto failure;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
*node = new;
|
*node = new; new = NULL;
|
||||||
{ret = ISO_SUCCESS; goto ex;}
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
|
|
||||||
failure:;
|
ex:;
|
||||||
/* todo: stuff any possible memory leak here */
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
free(name);
|
free(name);
|
||||||
free(new);
|
if (new != NULL)
|
||||||
ex:;
|
iso_node_unref(new);
|
||||||
LIBISO_FREE_MEM(dest);
|
LIBISO_FREE_MEM(dest);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -3239,13 +3386,14 @@ static
|
|||||||
int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
||||||
IsoDataSource *src, uint32_t iso_image_size, int flag)
|
IsoDataSource *src, uint32_t iso_image_size, int flag)
|
||||||
{
|
{
|
||||||
int i, ret, section_count, todo, chunk;
|
int i, j, ret, section_count, todo, chunk;
|
||||||
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
|
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
|
||||||
struct iso_file_section *sections = NULL;
|
struct iso_file_section *sections = NULL;
|
||||||
struct el_torito_boot_image *boot;
|
struct el_torito_boot_image *boot;
|
||||||
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
|
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
|
||||||
IsoStream *stream = NULL;
|
IsoStream *stream = NULL;
|
||||||
IsoFile *boot_file;
|
IsoFile *boot_file;
|
||||||
|
uint64_t blk;
|
||||||
|
|
||||||
if (image->bootcat == NULL)
|
if (image->bootcat == NULL)
|
||||||
{ret = ISO_SUCCESS; goto ex;}
|
{ret = ISO_SUCCESS; goto ex;}
|
||||||
@ -3254,6 +3402,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
|||||||
boot = image->bootcat->bootimages[i];
|
boot = image->bootcat->bootimages[i];
|
||||||
boot_file = boot->image;
|
boot_file = boot->image;
|
||||||
boot->seems_boot_info_table = 0;
|
boot->seems_boot_info_table = 0;
|
||||||
|
boot->seems_grub2_boot_info = 0;
|
||||||
img_size = iso_file_get_size(boot_file);
|
img_size = iso_file_get_size(boot_file);
|
||||||
if (img_size > Libisofs_boot_image_max_sizE || img_size < 64)
|
if (img_size > Libisofs_boot_image_max_sizE || img_size < 64)
|
||||||
continue;
|
continue;
|
||||||
@ -3319,6 +3468,16 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
|||||||
goto ex;
|
goto ex;
|
||||||
if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
|
if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
|
||||||
boot->seems_boot_info_table = 1;
|
boot->seems_boot_info_table = 1;
|
||||||
|
|
||||||
|
if (img_size >= Libisofs_grub2_elto_patch_poS + 8) {
|
||||||
|
blk = 0;
|
||||||
|
for (j = Libisofs_grub2_elto_patch_poS + 7;
|
||||||
|
j >= Libisofs_grub2_elto_patch_poS; j--)
|
||||||
|
blk = (blk << 8) | boot_image_buf[j];
|
||||||
|
if (blk == img_lba * 4 + Libisofs_grub2_elto_patch_offsT)
|
||||||
|
boot->seems_grub2_boot_info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
free(boot_image_buf);
|
free(boot_image_buf);
|
||||||
boot_image_buf = NULL;
|
boot_image_buf = NULL;
|
||||||
}
|
}
|
||||||
@ -3524,7 +3683,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
/* warn about hidden images */
|
/* warn about hidden images */
|
||||||
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
|
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
|
||||||
"Found hidden El-Torito image. Its size could not "
|
"Found hidden El-Torito image. Its size could not "
|
||||||
"be figure out, so image modify or boot image "
|
"be figured out, so image modify or boot image "
|
||||||
"patching may lead to bad results.");
|
"patching may lead to bad results.");
|
||||||
}
|
}
|
||||||
if (image->bootcat->node == NULL) {
|
if (image->bootcat->node == NULL) {
|
||||||
@ -3556,12 +3715,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
|
|
||||||
iso_node_builder_unref(image->builder);
|
iso_node_builder_unref(image->builder);
|
||||||
|
|
||||||
/* free old root */
|
|
||||||
iso_node_unref((IsoNode*)oldroot);
|
|
||||||
|
|
||||||
/* free old boot catalog */
|
|
||||||
el_torito_boot_catalog_free(oldbootcat);
|
|
||||||
|
|
||||||
/* set volume attributes */
|
/* set volume attributes */
|
||||||
iso_image_set_volset_id(image, data->volset_id);
|
iso_image_set_volset_id(image, data->volset_id);
|
||||||
iso_image_set_volume_id(image, data->volume_id);
|
iso_image_set_volume_id(image, data->volume_id);
|
||||||
@ -3572,6 +3725,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
iso_image_set_copyright_file_id(image, data->copyright_file_id);
|
iso_image_set_copyright_file_id(image, data->copyright_file_id);
|
||||||
iso_image_set_abstract_file_id(image, data->abstract_file_id);
|
iso_image_set_abstract_file_id(image, data->abstract_file_id);
|
||||||
iso_image_set_biblio_file_id(image, data->biblio_file_id);
|
iso_image_set_biblio_file_id(image, data->biblio_file_id);
|
||||||
|
iso_image_set_pvd_times(image, data->creation_time,
|
||||||
|
data->modification_time, data->expiration_time, data->effective_time);
|
||||||
|
|
||||||
if (features != NULL) {
|
if (features != NULL) {
|
||||||
*features = malloc(sizeof(IsoReadImageFeatures));
|
*features = malloc(sizeof(IsoReadImageFeatures));
|
||||||
@ -3650,7 +3805,9 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
iso_node_unref((IsoNode*)image->root);
|
iso_node_unref((IsoNode*)image->root);
|
||||||
el_torito_boot_catalog_free(image->bootcat);
|
el_torito_boot_catalog_free(image->bootcat);
|
||||||
image->root = oldroot;
|
image->root = oldroot;
|
||||||
|
oldroot = NULL;
|
||||||
image->bootcat = oldbootcat;
|
image->bootcat = oldbootcat;
|
||||||
|
oldbootcat = NULL;
|
||||||
image->checksum_array = old_checksum_array;
|
image->checksum_array = old_checksum_array;
|
||||||
old_checksum_array = NULL;
|
old_checksum_array = NULL;
|
||||||
|
|
||||||
@ -3660,6 +3817,14 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
image->fs = fsback;
|
image->fs = fsback;
|
||||||
image->builder = blback;
|
image->builder = blback;
|
||||||
|
|
||||||
|
/* free old root */
|
||||||
|
if (oldroot != NULL)
|
||||||
|
iso_node_unref((IsoNode*)oldroot);
|
||||||
|
|
||||||
|
/* free old boot catalog */
|
||||||
|
if (oldbootcat != NULL)
|
||||||
|
el_torito_boot_catalog_free(oldbootcat);
|
||||||
|
|
||||||
if (catalog != NULL)
|
if (catalog != NULL)
|
||||||
el_torito_boot_catalog_free(catalog);
|
el_torito_boot_catalog_free(catalog);
|
||||||
if (boot_image != NULL)
|
if (boot_image != NULL)
|
||||||
|
1841
libisofs/hfsplus.c
Normal file
1841
libisofs/hfsplus.c
Normal file
File diff suppressed because it is too large
Load Diff
197
libisofs/hfsplus.h
Normal file
197
libisofs/hfsplus.h
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 Vladimir Serbinenko
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare HFS+ related structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIBISO_HFSPLUS_H
|
||||||
|
#define LIBISO_HFSPLUS_H
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
#define LIBISO_HFSPLUS_NAME_MAX 255
|
||||||
|
|
||||||
|
|
||||||
|
enum hfsplus_node_type {
|
||||||
|
HFSPLUS_DIR = 1,
|
||||||
|
HFSPLUS_FILE = 2,
|
||||||
|
HFSPLUS_DIR_THREAD = 3,
|
||||||
|
HFSPLUS_FILE_THREAD = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hfsplus_btree_node
|
||||||
|
{
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t cnt;
|
||||||
|
uint32_t strlen;
|
||||||
|
uint16_t *str;
|
||||||
|
uint32_t parent_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hfsplus_btree_level
|
||||||
|
{
|
||||||
|
uint32_t level_size;
|
||||||
|
struct hfsplus_btree_node *nodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hfsplus_node
|
||||||
|
{
|
||||||
|
/* Note: .type HFSPLUS_DIR_THREAD and HFSPLUS_FILE_THREAD do not own their
|
||||||
|
.name and .cmp_name. They have copies of others, if ever.
|
||||||
|
*/
|
||||||
|
uint16_t *name; /* Name in UTF-16BE, decomposed. */
|
||||||
|
uint16_t *cmp_name; /* Name used for comparing. */
|
||||||
|
|
||||||
|
IsoNode *node; /*< reference to the iso node */
|
||||||
|
|
||||||
|
enum { UNIX_NONE, UNIX_SYMLINK, UNIX_SPECIAL } unix_type;
|
||||||
|
uint32_t symlink_block;
|
||||||
|
char *symlink_dest;
|
||||||
|
|
||||||
|
enum hfsplus_node_type type;
|
||||||
|
IsoFileSrc *file;
|
||||||
|
uint32_t cat_id;
|
||||||
|
uint32_t parent_id;
|
||||||
|
uint32_t nchildren;
|
||||||
|
|
||||||
|
uint32_t strlen;
|
||||||
|
uint32_t used_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
int hfsplus_writer_create(Ecma119Image *target);
|
||||||
|
int hfsplus_tail_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
|
struct hfsplus_extent
|
||||||
|
{
|
||||||
|
/* The first block of a file on disk. */
|
||||||
|
uint32_t start;
|
||||||
|
/* The amount of blocks described by this extent. */
|
||||||
|
uint32_t count;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct hfsplus_forkdata
|
||||||
|
{
|
||||||
|
uint64_t size;
|
||||||
|
uint32_t clumpsize;
|
||||||
|
uint32_t blocks;
|
||||||
|
struct hfsplus_extent extents[8];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct hfsplus_volheader
|
||||||
|
{
|
||||||
|
uint16_t magic;
|
||||||
|
uint16_t version;
|
||||||
|
uint32_t attributes;
|
||||||
|
uint32_t last_mounted_version;
|
||||||
|
uint32_t journal;
|
||||||
|
uint32_t ctime;
|
||||||
|
uint32_t utime;
|
||||||
|
uint32_t backup_time;
|
||||||
|
uint32_t fsck_time;
|
||||||
|
uint32_t file_count;
|
||||||
|
uint32_t folder_count;
|
||||||
|
uint32_t blksize;
|
||||||
|
uint32_t total_blocks;
|
||||||
|
uint32_t free_blocks;
|
||||||
|
uint32_t next_allocation;
|
||||||
|
uint32_t rsrc_clumpsize;
|
||||||
|
uint32_t data_clumpsize;
|
||||||
|
uint32_t catalog_node_id;
|
||||||
|
uint32_t write_count;
|
||||||
|
uint64_t encodings_bitmap;
|
||||||
|
uint32_t ppc_bootdir;
|
||||||
|
uint32_t intel_bootfile;
|
||||||
|
/* Folder opened when disk is mounted. */
|
||||||
|
uint32_t showfolder;
|
||||||
|
uint32_t os9folder;
|
||||||
|
uint32_t unused;
|
||||||
|
uint32_t osxfolder;
|
||||||
|
uint64_t num_serial;
|
||||||
|
struct hfsplus_forkdata allocations_file;
|
||||||
|
struct hfsplus_forkdata extents_file;
|
||||||
|
struct hfsplus_forkdata catalog_file;
|
||||||
|
struct hfsplus_forkdata attrib_file;
|
||||||
|
struct hfsplus_forkdata startup_file;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct hfsplus_btnode
|
||||||
|
{
|
||||||
|
uint32_t next;
|
||||||
|
uint32_t prev;
|
||||||
|
int8_t type;
|
||||||
|
uint8_t height;
|
||||||
|
uint16_t count;
|
||||||
|
uint16_t unused;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* The header of a HFS+ B+ Tree. */
|
||||||
|
struct hfsplus_btheader
|
||||||
|
{
|
||||||
|
uint16_t depth;
|
||||||
|
uint32_t root;
|
||||||
|
uint32_t leaf_records;
|
||||||
|
uint32_t first_leaf_node;
|
||||||
|
uint32_t last_leaf_node;
|
||||||
|
uint16_t nodesize;
|
||||||
|
uint16_t keysize;
|
||||||
|
uint32_t total_nodes;
|
||||||
|
uint32_t free_nodes;
|
||||||
|
uint16_t reserved1;
|
||||||
|
uint32_t clump_size;
|
||||||
|
uint8_t btree_type;
|
||||||
|
uint8_t key_compare;
|
||||||
|
uint32_t attributes;
|
||||||
|
uint32_t reserved[16];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct hfsplus_catfile_thread
|
||||||
|
{
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint32_t parentid;
|
||||||
|
uint16_t namelen;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct hfsplus_catfile_common
|
||||||
|
{
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t flags;
|
||||||
|
uint32_t valence; /* for files: reserved. */
|
||||||
|
uint32_t fileid;
|
||||||
|
uint32_t ctime;
|
||||||
|
uint32_t mtime;
|
||||||
|
uint32_t attr_mtime;
|
||||||
|
uint32_t atime;
|
||||||
|
uint32_t backup_time;
|
||||||
|
uint32_t uid;
|
||||||
|
uint32_t gid;
|
||||||
|
uint8_t user_flags;
|
||||||
|
uint8_t group_flags;
|
||||||
|
uint16_t mode;
|
||||||
|
uint32_t special;
|
||||||
|
uint8_t file_type[4]; /* For folders: window size */
|
||||||
|
uint8_t file_creator[4]; /* For folders: window size */
|
||||||
|
uint8_t finder_info[24];
|
||||||
|
uint32_t text_encoding;
|
||||||
|
uint32_t reserved;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define HFSPLUS_MAX_DECOMPOSE_LEN 4
|
||||||
|
|
||||||
|
extern uint16_t (*hfsplus_decompose_pages[256])[HFSPLUS_MAX_DECOMPOSE_LEN + 1];
|
||||||
|
void make_hfsplus_decompose_pages();
|
||||||
|
|
||||||
|
extern uint16_t *hfsplus_class_pages[256];
|
||||||
|
void make_hfsplus_class_pages();
|
||||||
|
|
||||||
|
extern const uint16_t hfsplus_casefold[];
|
||||||
|
|
||||||
|
#endif /* LIBISO_HFSPLUS_H */
|
472
libisofs/hfsplus_case.c
Normal file
472
libisofs/hfsplus_case.c
Normal file
@ -0,0 +1,472 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 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
|
||||||
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps UTF-16BE double-byte characters to the representative of their
|
||||||
|
* equivalence class under the relation of HFS+ case-insensitivity.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libisofs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* The translation list utf16be_transl was generated by a program which
|
||||||
|
compared input and output of existing example code by Apple Inc.
|
||||||
|
found published on
|
||||||
|
http://developer.apple.com/legacy/mac/library/#technotes/tn/tn1150.html
|
||||||
|
|
||||||
|
Each deviation was recorded as pair of byte pairs. The first pair gives
|
||||||
|
the input, the second pair gives the output. If a byte pair is not mentioned
|
||||||
|
in this list as input, then it gets mapped to itself.
|
||||||
|
Pairs which get mapped to pair 0,0 shall be ignored with HFS+ comparisons.
|
||||||
|
|
||||||
|
Another comparison run verified that both implementations yield the same
|
||||||
|
character translation with all 65536 possible input bit patterns.
|
||||||
|
*/
|
||||||
|
static uint8_t utf16be_transl[] = {
|
||||||
|
0x00, 0x00, 0xff, 0xff,
|
||||||
|
0x00, 0x41, 0x00, 0x61,
|
||||||
|
0x00, 0x42, 0x00, 0x62,
|
||||||
|
0x00, 0x43, 0x00, 0x63,
|
||||||
|
0x00, 0x44, 0x00, 0x64,
|
||||||
|
0x00, 0x45, 0x00, 0x65,
|
||||||
|
0x00, 0x46, 0x00, 0x66,
|
||||||
|
0x00, 0x47, 0x00, 0x67,
|
||||||
|
0x00, 0x48, 0x00, 0x68,
|
||||||
|
0x00, 0x49, 0x00, 0x69,
|
||||||
|
0x00, 0x4a, 0x00, 0x6a,
|
||||||
|
0x00, 0x4b, 0x00, 0x6b,
|
||||||
|
0x00, 0x4c, 0x00, 0x6c,
|
||||||
|
0x00, 0x4d, 0x00, 0x6d,
|
||||||
|
0x00, 0x4e, 0x00, 0x6e,
|
||||||
|
0x00, 0x4f, 0x00, 0x6f,
|
||||||
|
0x00, 0x50, 0x00, 0x70,
|
||||||
|
0x00, 0x51, 0x00, 0x71,
|
||||||
|
0x00, 0x52, 0x00, 0x72,
|
||||||
|
0x00, 0x53, 0x00, 0x73,
|
||||||
|
0x00, 0x54, 0x00, 0x74,
|
||||||
|
0x00, 0x55, 0x00, 0x75,
|
||||||
|
0x00, 0x56, 0x00, 0x76,
|
||||||
|
0x00, 0x57, 0x00, 0x77,
|
||||||
|
0x00, 0x58, 0x00, 0x78,
|
||||||
|
0x00, 0x59, 0x00, 0x79,
|
||||||
|
0x00, 0x5a, 0x00, 0x7a,
|
||||||
|
0x00, 0xc6, 0x00, 0xe6,
|
||||||
|
0x00, 0xd0, 0x00, 0xf0,
|
||||||
|
0x00, 0xd8, 0x00, 0xf8,
|
||||||
|
0x00, 0xde, 0x00, 0xfe,
|
||||||
|
0x01, 0x10, 0x01, 0x11,
|
||||||
|
0x01, 0x26, 0x01, 0x27,
|
||||||
|
0x01, 0x32, 0x01, 0x33,
|
||||||
|
0x01, 0x3f, 0x01, 0x40,
|
||||||
|
0x01, 0x41, 0x01, 0x42,
|
||||||
|
0x01, 0x4a, 0x01, 0x4b,
|
||||||
|
0x01, 0x52, 0x01, 0x53,
|
||||||
|
0x01, 0x66, 0x01, 0x67,
|
||||||
|
0x01, 0x81, 0x02, 0x53,
|
||||||
|
0x01, 0x82, 0x01, 0x83,
|
||||||
|
0x01, 0x84, 0x01, 0x85,
|
||||||
|
0x01, 0x86, 0x02, 0x54,
|
||||||
|
0x01, 0x87, 0x01, 0x88,
|
||||||
|
0x01, 0x89, 0x02, 0x56,
|
||||||
|
0x01, 0x8a, 0x02, 0x57,
|
||||||
|
0x01, 0x8b, 0x01, 0x8c,
|
||||||
|
0x01, 0x8e, 0x01, 0xdd,
|
||||||
|
0x01, 0x8f, 0x02, 0x59,
|
||||||
|
0x01, 0x90, 0x02, 0x5b,
|
||||||
|
0x01, 0x91, 0x01, 0x92,
|
||||||
|
0x01, 0x93, 0x02, 0x60,
|
||||||
|
0x01, 0x94, 0x02, 0x63,
|
||||||
|
0x01, 0x96, 0x02, 0x69,
|
||||||
|
0x01, 0x97, 0x02, 0x68,
|
||||||
|
0x01, 0x98, 0x01, 0x99,
|
||||||
|
0x01, 0x9c, 0x02, 0x6f,
|
||||||
|
0x01, 0x9d, 0x02, 0x72,
|
||||||
|
0x01, 0x9f, 0x02, 0x75,
|
||||||
|
0x01, 0xa2, 0x01, 0xa3,
|
||||||
|
0x01, 0xa4, 0x01, 0xa5,
|
||||||
|
0x01, 0xa7, 0x01, 0xa8,
|
||||||
|
0x01, 0xa9, 0x02, 0x83,
|
||||||
|
0x01, 0xac, 0x01, 0xad,
|
||||||
|
0x01, 0xae, 0x02, 0x88,
|
||||||
|
0x01, 0xb1, 0x02, 0x8a,
|
||||||
|
0x01, 0xb2, 0x02, 0x8b,
|
||||||
|
0x01, 0xb3, 0x01, 0xb4,
|
||||||
|
0x01, 0xb5, 0x01, 0xb6,
|
||||||
|
0x01, 0xb7, 0x02, 0x92,
|
||||||
|
0x01, 0xb8, 0x01, 0xb9,
|
||||||
|
0x01, 0xbc, 0x01, 0xbd,
|
||||||
|
0x01, 0xc4, 0x01, 0xc6,
|
||||||
|
0x01, 0xc5, 0x01, 0xc6,
|
||||||
|
0x01, 0xc7, 0x01, 0xc9,
|
||||||
|
0x01, 0xc8, 0x01, 0xc9,
|
||||||
|
0x01, 0xca, 0x01, 0xcc,
|
||||||
|
0x01, 0xcb, 0x01, 0xcc,
|
||||||
|
0x01, 0xe4, 0x01, 0xe5,
|
||||||
|
0x01, 0xf1, 0x01, 0xf3,
|
||||||
|
0x01, 0xf2, 0x01, 0xf3,
|
||||||
|
0x03, 0x91, 0x03, 0xb1,
|
||||||
|
0x03, 0x92, 0x03, 0xb2,
|
||||||
|
0x03, 0x93, 0x03, 0xb3,
|
||||||
|
0x03, 0x94, 0x03, 0xb4,
|
||||||
|
0x03, 0x95, 0x03, 0xb5,
|
||||||
|
0x03, 0x96, 0x03, 0xb6,
|
||||||
|
0x03, 0x97, 0x03, 0xb7,
|
||||||
|
0x03, 0x98, 0x03, 0xb8,
|
||||||
|
0x03, 0x99, 0x03, 0xb9,
|
||||||
|
0x03, 0x9a, 0x03, 0xba,
|
||||||
|
0x03, 0x9b, 0x03, 0xbb,
|
||||||
|
0x03, 0x9c, 0x03, 0xbc,
|
||||||
|
0x03, 0x9d, 0x03, 0xbd,
|
||||||
|
0x03, 0x9e, 0x03, 0xbe,
|
||||||
|
0x03, 0x9f, 0x03, 0xbf,
|
||||||
|
0x03, 0xa0, 0x03, 0xc0,
|
||||||
|
0x03, 0xa1, 0x03, 0xc1,
|
||||||
|
0x03, 0xa3, 0x03, 0xc3,
|
||||||
|
0x03, 0xa4, 0x03, 0xc4,
|
||||||
|
0x03, 0xa5, 0x03, 0xc5,
|
||||||
|
0x03, 0xa6, 0x03, 0xc6,
|
||||||
|
0x03, 0xa7, 0x03, 0xc7,
|
||||||
|
0x03, 0xa8, 0x03, 0xc8,
|
||||||
|
0x03, 0xa9, 0x03, 0xc9,
|
||||||
|
0x03, 0xe2, 0x03, 0xe3,
|
||||||
|
0x03, 0xe4, 0x03, 0xe5,
|
||||||
|
0x03, 0xe6, 0x03, 0xe7,
|
||||||
|
0x03, 0xe8, 0x03, 0xe9,
|
||||||
|
0x03, 0xea, 0x03, 0xeb,
|
||||||
|
0x03, 0xec, 0x03, 0xed,
|
||||||
|
0x03, 0xee, 0x03, 0xef,
|
||||||
|
0x04, 0x02, 0x04, 0x52,
|
||||||
|
0x04, 0x04, 0x04, 0x54,
|
||||||
|
0x04, 0x05, 0x04, 0x55,
|
||||||
|
0x04, 0x06, 0x04, 0x56,
|
||||||
|
0x04, 0x08, 0x04, 0x58,
|
||||||
|
0x04, 0x09, 0x04, 0x59,
|
||||||
|
0x04, 0x0a, 0x04, 0x5a,
|
||||||
|
0x04, 0x0b, 0x04, 0x5b,
|
||||||
|
0x04, 0x0f, 0x04, 0x5f,
|
||||||
|
0x04, 0x10, 0x04, 0x30,
|
||||||
|
0x04, 0x11, 0x04, 0x31,
|
||||||
|
0x04, 0x12, 0x04, 0x32,
|
||||||
|
0x04, 0x13, 0x04, 0x33,
|
||||||
|
0x04, 0x14, 0x04, 0x34,
|
||||||
|
0x04, 0x15, 0x04, 0x35,
|
||||||
|
0x04, 0x16, 0x04, 0x36,
|
||||||
|
0x04, 0x17, 0x04, 0x37,
|
||||||
|
0x04, 0x18, 0x04, 0x38,
|
||||||
|
0x04, 0x1a, 0x04, 0x3a,
|
||||||
|
0x04, 0x1b, 0x04, 0x3b,
|
||||||
|
0x04, 0x1c, 0x04, 0x3c,
|
||||||
|
0x04, 0x1d, 0x04, 0x3d,
|
||||||
|
0x04, 0x1e, 0x04, 0x3e,
|
||||||
|
0x04, 0x1f, 0x04, 0x3f,
|
||||||
|
0x04, 0x20, 0x04, 0x40,
|
||||||
|
0x04, 0x21, 0x04, 0x41,
|
||||||
|
0x04, 0x22, 0x04, 0x42,
|
||||||
|
0x04, 0x23, 0x04, 0x43,
|
||||||
|
0x04, 0x24, 0x04, 0x44,
|
||||||
|
0x04, 0x25, 0x04, 0x45,
|
||||||
|
0x04, 0x26, 0x04, 0x46,
|
||||||
|
0x04, 0x27, 0x04, 0x47,
|
||||||
|
0x04, 0x28, 0x04, 0x48,
|
||||||
|
0x04, 0x29, 0x04, 0x49,
|
||||||
|
0x04, 0x2a, 0x04, 0x4a,
|
||||||
|
0x04, 0x2b, 0x04, 0x4b,
|
||||||
|
0x04, 0x2c, 0x04, 0x4c,
|
||||||
|
0x04, 0x2d, 0x04, 0x4d,
|
||||||
|
0x04, 0x2e, 0x04, 0x4e,
|
||||||
|
0x04, 0x2f, 0x04, 0x4f,
|
||||||
|
0x04, 0x60, 0x04, 0x61,
|
||||||
|
0x04, 0x62, 0x04, 0x63,
|
||||||
|
0x04, 0x64, 0x04, 0x65,
|
||||||
|
0x04, 0x66, 0x04, 0x67,
|
||||||
|
0x04, 0x68, 0x04, 0x69,
|
||||||
|
0x04, 0x6a, 0x04, 0x6b,
|
||||||
|
0x04, 0x6c, 0x04, 0x6d,
|
||||||
|
0x04, 0x6e, 0x04, 0x6f,
|
||||||
|
0x04, 0x70, 0x04, 0x71,
|
||||||
|
0x04, 0x72, 0x04, 0x73,
|
||||||
|
0x04, 0x74, 0x04, 0x75,
|
||||||
|
0x04, 0x78, 0x04, 0x79,
|
||||||
|
0x04, 0x7a, 0x04, 0x7b,
|
||||||
|
0x04, 0x7c, 0x04, 0x7d,
|
||||||
|
0x04, 0x7e, 0x04, 0x7f,
|
||||||
|
0x04, 0x80, 0x04, 0x81,
|
||||||
|
0x04, 0x90, 0x04, 0x91,
|
||||||
|
0x04, 0x92, 0x04, 0x93,
|
||||||
|
0x04, 0x94, 0x04, 0x95,
|
||||||
|
0x04, 0x96, 0x04, 0x97,
|
||||||
|
0x04, 0x98, 0x04, 0x99,
|
||||||
|
0x04, 0x9a, 0x04, 0x9b,
|
||||||
|
0x04, 0x9c, 0x04, 0x9d,
|
||||||
|
0x04, 0x9e, 0x04, 0x9f,
|
||||||
|
0x04, 0xa0, 0x04, 0xa1,
|
||||||
|
0x04, 0xa2, 0x04, 0xa3,
|
||||||
|
0x04, 0xa4, 0x04, 0xa5,
|
||||||
|
0x04, 0xa6, 0x04, 0xa7,
|
||||||
|
0x04, 0xa8, 0x04, 0xa9,
|
||||||
|
0x04, 0xaa, 0x04, 0xab,
|
||||||
|
0x04, 0xac, 0x04, 0xad,
|
||||||
|
0x04, 0xae, 0x04, 0xaf,
|
||||||
|
0x04, 0xb0, 0x04, 0xb1,
|
||||||
|
0x04, 0xb2, 0x04, 0xb3,
|
||||||
|
0x04, 0xb4, 0x04, 0xb5,
|
||||||
|
0x04, 0xb6, 0x04, 0xb7,
|
||||||
|
0x04, 0xb8, 0x04, 0xb9,
|
||||||
|
0x04, 0xba, 0x04, 0xbb,
|
||||||
|
0x04, 0xbc, 0x04, 0xbd,
|
||||||
|
0x04, 0xbe, 0x04, 0xbf,
|
||||||
|
0x04, 0xc3, 0x04, 0xc4,
|
||||||
|
0x04, 0xc7, 0x04, 0xc8,
|
||||||
|
0x04, 0xcb, 0x04, 0xcc,
|
||||||
|
0x05, 0x31, 0x05, 0x61,
|
||||||
|
0x05, 0x32, 0x05, 0x62,
|
||||||
|
0x05, 0x33, 0x05, 0x63,
|
||||||
|
0x05, 0x34, 0x05, 0x64,
|
||||||
|
0x05, 0x35, 0x05, 0x65,
|
||||||
|
0x05, 0x36, 0x05, 0x66,
|
||||||
|
0x05, 0x37, 0x05, 0x67,
|
||||||
|
0x05, 0x38, 0x05, 0x68,
|
||||||
|
0x05, 0x39, 0x05, 0x69,
|
||||||
|
0x05, 0x3a, 0x05, 0x6a,
|
||||||
|
0x05, 0x3b, 0x05, 0x6b,
|
||||||
|
0x05, 0x3c, 0x05, 0x6c,
|
||||||
|
0x05, 0x3d, 0x05, 0x6d,
|
||||||
|
0x05, 0x3e, 0x05, 0x6e,
|
||||||
|
0x05, 0x3f, 0x05, 0x6f,
|
||||||
|
0x05, 0x40, 0x05, 0x70,
|
||||||
|
0x05, 0x41, 0x05, 0x71,
|
||||||
|
0x05, 0x42, 0x05, 0x72,
|
||||||
|
0x05, 0x43, 0x05, 0x73,
|
||||||
|
0x05, 0x44, 0x05, 0x74,
|
||||||
|
0x05, 0x45, 0x05, 0x75,
|
||||||
|
0x05, 0x46, 0x05, 0x76,
|
||||||
|
0x05, 0x47, 0x05, 0x77,
|
||||||
|
0x05, 0x48, 0x05, 0x78,
|
||||||
|
0x05, 0x49, 0x05, 0x79,
|
||||||
|
0x05, 0x4a, 0x05, 0x7a,
|
||||||
|
0x05, 0x4b, 0x05, 0x7b,
|
||||||
|
0x05, 0x4c, 0x05, 0x7c,
|
||||||
|
0x05, 0x4d, 0x05, 0x7d,
|
||||||
|
0x05, 0x4e, 0x05, 0x7e,
|
||||||
|
0x05, 0x4f, 0x05, 0x7f,
|
||||||
|
0x05, 0x50, 0x05, 0x80,
|
||||||
|
0x05, 0x51, 0x05, 0x81,
|
||||||
|
0x05, 0x52, 0x05, 0x82,
|
||||||
|
0x05, 0x53, 0x05, 0x83,
|
||||||
|
0x05, 0x54, 0x05, 0x84,
|
||||||
|
0x05, 0x55, 0x05, 0x85,
|
||||||
|
0x05, 0x56, 0x05, 0x86,
|
||||||
|
0x10, 0xa0, 0x10, 0xd0,
|
||||||
|
0x10, 0xa1, 0x10, 0xd1,
|
||||||
|
0x10, 0xa2, 0x10, 0xd2,
|
||||||
|
0x10, 0xa3, 0x10, 0xd3,
|
||||||
|
0x10, 0xa4, 0x10, 0xd4,
|
||||||
|
0x10, 0xa5, 0x10, 0xd5,
|
||||||
|
0x10, 0xa6, 0x10, 0xd6,
|
||||||
|
0x10, 0xa7, 0x10, 0xd7,
|
||||||
|
0x10, 0xa8, 0x10, 0xd8,
|
||||||
|
0x10, 0xa9, 0x10, 0xd9,
|
||||||
|
0x10, 0xaa, 0x10, 0xda,
|
||||||
|
0x10, 0xab, 0x10, 0xdb,
|
||||||
|
0x10, 0xac, 0x10, 0xdc,
|
||||||
|
0x10, 0xad, 0x10, 0xdd,
|
||||||
|
0x10, 0xae, 0x10, 0xde,
|
||||||
|
0x10, 0xaf, 0x10, 0xdf,
|
||||||
|
0x10, 0xb0, 0x10, 0xe0,
|
||||||
|
0x10, 0xb1, 0x10, 0xe1,
|
||||||
|
0x10, 0xb2, 0x10, 0xe2,
|
||||||
|
0x10, 0xb3, 0x10, 0xe3,
|
||||||
|
0x10, 0xb4, 0x10, 0xe4,
|
||||||
|
0x10, 0xb5, 0x10, 0xe5,
|
||||||
|
0x10, 0xb6, 0x10, 0xe6,
|
||||||
|
0x10, 0xb7, 0x10, 0xe7,
|
||||||
|
0x10, 0xb8, 0x10, 0xe8,
|
||||||
|
0x10, 0xb9, 0x10, 0xe9,
|
||||||
|
0x10, 0xba, 0x10, 0xea,
|
||||||
|
0x10, 0xbb, 0x10, 0xeb,
|
||||||
|
0x10, 0xbc, 0x10, 0xec,
|
||||||
|
0x10, 0xbd, 0x10, 0xed,
|
||||||
|
0x10, 0xbe, 0x10, 0xee,
|
||||||
|
0x10, 0xbf, 0x10, 0xef,
|
||||||
|
0x10, 0xc0, 0x10, 0xf0,
|
||||||
|
0x10, 0xc1, 0x10, 0xf1,
|
||||||
|
0x10, 0xc2, 0x10, 0xf2,
|
||||||
|
0x10, 0xc3, 0x10, 0xf3,
|
||||||
|
0x10, 0xc4, 0x10, 0xf4,
|
||||||
|
0x10, 0xc5, 0x10, 0xf5,
|
||||||
|
0x20, 0x0c, 0x00, 0x00,
|
||||||
|
0x20, 0x0d, 0x00, 0x00,
|
||||||
|
0x20, 0x0e, 0x00, 0x00,
|
||||||
|
0x20, 0x0f, 0x00, 0x00,
|
||||||
|
0x20, 0x2a, 0x00, 0x00,
|
||||||
|
0x20, 0x2b, 0x00, 0x00,
|
||||||
|
0x20, 0x2c, 0x00, 0x00,
|
||||||
|
0x20, 0x2d, 0x00, 0x00,
|
||||||
|
0x20, 0x2e, 0x00, 0x00,
|
||||||
|
0x20, 0x6a, 0x00, 0x00,
|
||||||
|
0x20, 0x6b, 0x00, 0x00,
|
||||||
|
0x20, 0x6c, 0x00, 0x00,
|
||||||
|
0x20, 0x6d, 0x00, 0x00,
|
||||||
|
0x20, 0x6e, 0x00, 0x00,
|
||||||
|
0x20, 0x6f, 0x00, 0x00,
|
||||||
|
0x21, 0x60, 0x21, 0x70,
|
||||||
|
0x21, 0x61, 0x21, 0x71,
|
||||||
|
0x21, 0x62, 0x21, 0x72,
|
||||||
|
0x21, 0x63, 0x21, 0x73,
|
||||||
|
0x21, 0x64, 0x21, 0x74,
|
||||||
|
0x21, 0x65, 0x21, 0x75,
|
||||||
|
0x21, 0x66, 0x21, 0x76,
|
||||||
|
0x21, 0x67, 0x21, 0x77,
|
||||||
|
0x21, 0x68, 0x21, 0x78,
|
||||||
|
0x21, 0x69, 0x21, 0x79,
|
||||||
|
0x21, 0x6a, 0x21, 0x7a,
|
||||||
|
0x21, 0x6b, 0x21, 0x7b,
|
||||||
|
0x21, 0x6c, 0x21, 0x7c,
|
||||||
|
0x21, 0x6d, 0x21, 0x7d,
|
||||||
|
0x21, 0x6e, 0x21, 0x7e,
|
||||||
|
0x21, 0x6f, 0x21, 0x7f,
|
||||||
|
0xfe, 0xff, 0x00, 0x00,
|
||||||
|
0xff, 0x21, 0xff, 0x41,
|
||||||
|
0xff, 0x22, 0xff, 0x42,
|
||||||
|
0xff, 0x23, 0xff, 0x43,
|
||||||
|
0xff, 0x24, 0xff, 0x44,
|
||||||
|
0xff, 0x25, 0xff, 0x45,
|
||||||
|
0xff, 0x26, 0xff, 0x46,
|
||||||
|
0xff, 0x27, 0xff, 0x47,
|
||||||
|
0xff, 0x28, 0xff, 0x48,
|
||||||
|
0xff, 0x29, 0xff, 0x49,
|
||||||
|
0xff, 0x2a, 0xff, 0x4a,
|
||||||
|
0xff, 0x2b, 0xff, 0x4b,
|
||||||
|
0xff, 0x2c, 0xff, 0x4c,
|
||||||
|
0xff, 0x2d, 0xff, 0x4d,
|
||||||
|
0xff, 0x2e, 0xff, 0x4e,
|
||||||
|
0xff, 0x2f, 0xff, 0x4f,
|
||||||
|
0xff, 0x30, 0xff, 0x50,
|
||||||
|
0xff, 0x31, 0xff, 0x51,
|
||||||
|
0xff, 0x32, 0xff, 0x52,
|
||||||
|
0xff, 0x33, 0xff, 0x53,
|
||||||
|
0xff, 0x34, 0xff, 0x54,
|
||||||
|
0xff, 0x35, 0xff, 0x55,
|
||||||
|
0xff, 0x36, 0xff, 0x56,
|
||||||
|
0xff, 0x37, 0xff, 0x57,
|
||||||
|
0xff, 0x38, 0xff, 0x58,
|
||||||
|
0xff, 0x39, 0xff, 0x59,
|
||||||
|
0xff, 0x3a, 0xff, 0x5a,
|
||||||
|
0x00
|
||||||
|
};
|
||||||
|
static int utf16be_transl_count = 329;
|
||||||
|
|
||||||
|
/* These are the start indice in utf16be_transl[] for the page numbers 0 to 9
|
||||||
|
as classified by function what_page().
|
||||||
|
As soon as the first byte of the input pair in utf16be_transl[] changes,
|
||||||
|
the search can be ended and output is equal to input.
|
||||||
|
If page -1 is returned by what_page(), then input is equal to output.
|
||||||
|
*/
|
||||||
|
static int utf16be_transl_starts[] = {
|
||||||
|
0, 31, 81, 112, 195, 233, 271, 286, 302, 303
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int what_page(uint16_t x)
|
||||||
|
{
|
||||||
|
switch(((uint8_t *) &x)[0]) {
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
case 1:
|
||||||
|
return 1;
|
||||||
|
case 3:
|
||||||
|
return 2;
|
||||||
|
case 4:
|
||||||
|
return 3;
|
||||||
|
case 5:
|
||||||
|
return 4;
|
||||||
|
case 16:
|
||||||
|
return 5;
|
||||||
|
case 32:
|
||||||
|
return 6;
|
||||||
|
case 33:
|
||||||
|
return 7;
|
||||||
|
case 254:
|
||||||
|
return 8;
|
||||||
|
case 255:
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
|
return -1; /* no mapping */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Accelerator for the ASCII subset which is expected to be the most
|
||||||
|
frequently used one.
|
||||||
|
*/
|
||||||
|
static uint16_t cmp_name_page0(uint16_t x)
|
||||||
|
{
|
||||||
|
uint8_t *low;
|
||||||
|
|
||||||
|
low = ((uint8_t *) &x) + 1;
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
return 0xffff;
|
||||||
|
if (*low <= 0x40)
|
||||||
|
;
|
||||||
|
else if (*low <= 0x5a)
|
||||||
|
*low = *low + 0x20;
|
||||||
|
else if (*low < 0xc6)
|
||||||
|
;
|
||||||
|
else if (*low == 0xc6)
|
||||||
|
*low = 0xe6;
|
||||||
|
else if (*low == 0xd0)
|
||||||
|
*low = 0xf0;
|
||||||
|
else if (*low == 0xd8)
|
||||||
|
*low = 0xf8;
|
||||||
|
else if (*low == 0xde)
|
||||||
|
*low = 0xfe;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Converts a character into the representative of its HFS+ equivalence
|
||||||
|
class.
|
||||||
|
@param x The UTF-16BE character to be converted.
|
||||||
|
@return 0 = ignore character with comparisons
|
||||||
|
else the case-insensitive character.
|
||||||
|
*/
|
||||||
|
uint16_t iso_hfsplus_cichar(uint16_t x)
|
||||||
|
{
|
||||||
|
int page, i;
|
||||||
|
uint16_t ret;
|
||||||
|
uint8_t low, high;
|
||||||
|
|
||||||
|
high = ((uint8_t *) &x)[0];
|
||||||
|
low = ((uint8_t *) &x)[1];
|
||||||
|
|
||||||
|
page = what_page(x);
|
||||||
|
if (page < 0)
|
||||||
|
return x; /* No translation needed */
|
||||||
|
if (page == 0)
|
||||||
|
return cmp_name_page0(x); /* Accelerator for ASCII subset */
|
||||||
|
|
||||||
|
for (i = utf16be_transl_starts[page] * 4; i < utf16be_transl_count * 4;
|
||||||
|
i += 4) {
|
||||||
|
if (utf16be_transl[i] != high)
|
||||||
|
break;
|
||||||
|
if (utf16be_transl[i + 1] == low) {
|
||||||
|
((uint8_t *) &ret)[0] = utf16be_transl[i + 2];
|
||||||
|
((uint8_t *) &ret)[1] = utf16be_transl[i + 3];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
460
libisofs/hfsplus_classes.c
Normal file
460
libisofs/hfsplus_classes.c
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Based on Unicode 3.2.0.
|
||||||
|
* See http://www.unicode.org/copyright.html
|
||||||
|
* Quote from there:
|
||||||
|
* "Copyright (c) 1991-2012 Unicode, Inc. All rights reserved.
|
||||||
|
* [...]
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of the Unicode data files and any associated documentation
|
||||||
|
* (the "Data Files") or Unicode software and any associated documentation
|
||||||
|
* (the "Software") to deal in the Data Files or Software without restriction,
|
||||||
|
* including without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, and/or sell copies of the Data Files or Software, and to permit
|
||||||
|
* persons to whom the Data Files or Software are furnished to do so, provided
|
||||||
|
* that (a) the above copyright notice(s) and this permission notice appear
|
||||||
|
* with all copies of the Data Files or Software, (b) both the above copyright
|
||||||
|
* notice(s) and this permission notice appear in associated documentation,
|
||||||
|
* and (c) there is clear notice in each modified Data File or in the Software
|
||||||
|
* as well as in the documentation associated with the Data File(s) or
|
||||||
|
* Software that the data or software has been modified."
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* For this particular implementation:
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Vladimir Serbinenko
|
||||||
|
* Copyright (c) 2012 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
|
||||||
|
* or later as published by the Free Software Foundation.
|
||||||
|
* See COPYING file for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hfsplus.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* This encodes a matrix of page and character, with 16-bit words as elements.
|
||||||
|
Initially the matrix is filled with zeros.
|
||||||
|
1: The first element is the page number.
|
||||||
|
If it is equal or lower than the previous one, then the matrix is done.
|
||||||
|
2: The next element is the character number
|
||||||
|
If it is equal or lower than the previous one, the page is done. Goto 1.
|
||||||
|
3: The next element is the byte value. Goto 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uint16_t class_page_data[] = {
|
||||||
|
|
||||||
|
/* page 03 */
|
||||||
|
0x03,
|
||||||
|
0x00, 0x230,
|
||||||
|
0x01, 0x230,
|
||||||
|
0x02, 0x230,
|
||||||
|
0x03, 0x230,
|
||||||
|
0x04, 0x230,
|
||||||
|
0x05, 0x230,
|
||||||
|
0x06, 0x230,
|
||||||
|
0x07, 0x230,
|
||||||
|
0x08, 0x230,
|
||||||
|
0x09, 0x230,
|
||||||
|
0x0a, 0x230,
|
||||||
|
0x0b, 0x230,
|
||||||
|
0x0c, 0x230,
|
||||||
|
0x0d, 0x230,
|
||||||
|
0x0e, 0x230,
|
||||||
|
0x0f, 0x230,
|
||||||
|
0x10, 0x230,
|
||||||
|
0x11, 0x230,
|
||||||
|
0x12, 0x230,
|
||||||
|
0x13, 0x230,
|
||||||
|
0x14, 0x230,
|
||||||
|
0x15, 0x232,
|
||||||
|
0x16, 0x220,
|
||||||
|
0x17, 0x220,
|
||||||
|
0x18, 0x220,
|
||||||
|
0x19, 0x220,
|
||||||
|
0x1a, 0x232,
|
||||||
|
0x1b, 0x216,
|
||||||
|
0x1c, 0x220,
|
||||||
|
0x1d, 0x220,
|
||||||
|
0x1e, 0x220,
|
||||||
|
0x1f, 0x220,
|
||||||
|
0x20, 0x220,
|
||||||
|
0x21, 0x202,
|
||||||
|
0x22, 0x202,
|
||||||
|
0x23, 0x220,
|
||||||
|
0x24, 0x220,
|
||||||
|
0x25, 0x220,
|
||||||
|
0x26, 0x220,
|
||||||
|
0x27, 0x202,
|
||||||
|
0x28, 0x202,
|
||||||
|
0x29, 0x220,
|
||||||
|
0x2a, 0x220,
|
||||||
|
0x2b, 0x220,
|
||||||
|
0x2c, 0x220,
|
||||||
|
0x2d, 0x220,
|
||||||
|
0x2e, 0x220,
|
||||||
|
0x2f, 0x220,
|
||||||
|
0x30, 0x220,
|
||||||
|
0x31, 0x220,
|
||||||
|
0x32, 0x220,
|
||||||
|
0x33, 0x220,
|
||||||
|
0x34, 0x1,
|
||||||
|
0x35, 0x1,
|
||||||
|
0x36, 0x1,
|
||||||
|
0x37, 0x1,
|
||||||
|
0x38, 0x1,
|
||||||
|
0x39, 0x220,
|
||||||
|
0x3a, 0x220,
|
||||||
|
0x3b, 0x220,
|
||||||
|
0x3c, 0x220,
|
||||||
|
0x3d, 0x230,
|
||||||
|
0x3e, 0x230,
|
||||||
|
0x3f, 0x230,
|
||||||
|
0x40, 0x230,
|
||||||
|
0x41, 0x230,
|
||||||
|
0x42, 0x230,
|
||||||
|
0x43, 0x230,
|
||||||
|
0x44, 0x230,
|
||||||
|
0x45, 0x240,
|
||||||
|
0x46, 0x230,
|
||||||
|
0x47, 0x220,
|
||||||
|
0x48, 0x220,
|
||||||
|
0x49, 0x220,
|
||||||
|
0x4a, 0x230,
|
||||||
|
0x4b, 0x230,
|
||||||
|
0x4c, 0x230,
|
||||||
|
0x4d, 0x220,
|
||||||
|
0x4e, 0x220,
|
||||||
|
0x60, 0x234,
|
||||||
|
0x61, 0x234,
|
||||||
|
0x62, 0x233,
|
||||||
|
0x63, 0x230,
|
||||||
|
0x64, 0x230,
|
||||||
|
0x65, 0x230,
|
||||||
|
0x66, 0x230,
|
||||||
|
0x67, 0x230,
|
||||||
|
0x68, 0x230,
|
||||||
|
0x69, 0x230,
|
||||||
|
0x6a, 0x230,
|
||||||
|
0x6b, 0x230,
|
||||||
|
0x6c, 0x230,
|
||||||
|
0x6d, 0x230,
|
||||||
|
0x6e, 0x230,
|
||||||
|
0x6f, 0x230,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page04 */
|
||||||
|
0x04,
|
||||||
|
0x83, 0x230,
|
||||||
|
0x84, 0x230,
|
||||||
|
0x85, 0x230,
|
||||||
|
0x86, 0x230,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page05 */
|
||||||
|
0x05,
|
||||||
|
0x91, 0x220,
|
||||||
|
0x92, 0x230,
|
||||||
|
0x93, 0x230,
|
||||||
|
0x94, 0x230,
|
||||||
|
0x95, 0x230,
|
||||||
|
0x96, 0x220,
|
||||||
|
0x97, 0x230,
|
||||||
|
0x98, 0x230,
|
||||||
|
0x99, 0x230,
|
||||||
|
0x9a, 0x222,
|
||||||
|
0x9b, 0x220,
|
||||||
|
0x9c, 0x230,
|
||||||
|
0x9d, 0x230,
|
||||||
|
0x9e, 0x230,
|
||||||
|
0x9f, 0x230,
|
||||||
|
0xa0, 0x230,
|
||||||
|
0xa1, 0x230,
|
||||||
|
0xa3, 0x220,
|
||||||
|
0xa4, 0x220,
|
||||||
|
0xa5, 0x220,
|
||||||
|
0xa6, 0x220,
|
||||||
|
0xa7, 0x220,
|
||||||
|
0xa8, 0x230,
|
||||||
|
0xa9, 0x230,
|
||||||
|
0xaa, 0x220,
|
||||||
|
0xab, 0x230,
|
||||||
|
0xac, 0x230,
|
||||||
|
0xad, 0x222,
|
||||||
|
0xae, 0x228,
|
||||||
|
0xaf, 0x230,
|
||||||
|
0xb0, 0x10,
|
||||||
|
0xb1, 0x11,
|
||||||
|
0xb2, 0x12,
|
||||||
|
0xb3, 0x13,
|
||||||
|
0xb4, 0x14,
|
||||||
|
0xb5, 0x15,
|
||||||
|
0xb6, 0x16,
|
||||||
|
0xb7, 0x17,
|
||||||
|
0xb8, 0x18,
|
||||||
|
0xb9, 0x19,
|
||||||
|
0xbb, 0x20,
|
||||||
|
0xbc, 0x21,
|
||||||
|
0xbd, 0x22,
|
||||||
|
0xbf, 0x23,
|
||||||
|
0xc1, 0x24,
|
||||||
|
0xc2, 0x25,
|
||||||
|
0xc4, 0x230,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page06 */
|
||||||
|
0x06,
|
||||||
|
0x4b, 0x27,
|
||||||
|
0x4c, 0x28,
|
||||||
|
0x4d, 0x29,
|
||||||
|
0x4e, 0x30,
|
||||||
|
0x4f, 0x31,
|
||||||
|
0x50, 0x32,
|
||||||
|
0x51, 0x33,
|
||||||
|
0x52, 0x34,
|
||||||
|
0x53, 0x230,
|
||||||
|
0x54, 0x230,
|
||||||
|
0x55, 0x220,
|
||||||
|
0x70, 0x35,
|
||||||
|
0xd6, 0x230,
|
||||||
|
0xd7, 0x230,
|
||||||
|
0xd8, 0x230,
|
||||||
|
0xd9, 0x230,
|
||||||
|
0xda, 0x230,
|
||||||
|
0xdb, 0x230,
|
||||||
|
0xdc, 0x230,
|
||||||
|
0xdf, 0x230,
|
||||||
|
0xe0, 0x230,
|
||||||
|
0xe1, 0x230,
|
||||||
|
0xe2, 0x230,
|
||||||
|
0xe3, 0x220,
|
||||||
|
0xe4, 0x230,
|
||||||
|
0xe7, 0x230,
|
||||||
|
0xe8, 0x230,
|
||||||
|
0xea, 0x220,
|
||||||
|
0xeb, 0x230,
|
||||||
|
0xec, 0x230,
|
||||||
|
0xed, 0x220,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page07 */
|
||||||
|
0x07,
|
||||||
|
0x11, 0x36,
|
||||||
|
0x30, 0x230,
|
||||||
|
0x31, 0x220,
|
||||||
|
0x32, 0x230,
|
||||||
|
0x33, 0x230,
|
||||||
|
0x34, 0x220,
|
||||||
|
0x35, 0x230,
|
||||||
|
0x36, 0x230,
|
||||||
|
0x37, 0x220,
|
||||||
|
0x38, 0x220,
|
||||||
|
0x39, 0x220,
|
||||||
|
0x3a, 0x230,
|
||||||
|
0x3b, 0x220,
|
||||||
|
0x3c, 0x220,
|
||||||
|
0x3d, 0x230,
|
||||||
|
0x3e, 0x220,
|
||||||
|
0x3f, 0x230,
|
||||||
|
0x40, 0x230,
|
||||||
|
0x41, 0x230,
|
||||||
|
0x42, 0x220,
|
||||||
|
0x43, 0x230,
|
||||||
|
0x44, 0x220,
|
||||||
|
0x45, 0x230,
|
||||||
|
0x46, 0x220,
|
||||||
|
0x47, 0x230,
|
||||||
|
0x48, 0x220,
|
||||||
|
0x49, 0x230,
|
||||||
|
0x4a, 0x230,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page09 */
|
||||||
|
0x09,
|
||||||
|
0x3c, 0x7,
|
||||||
|
0x4d, 0x9,
|
||||||
|
0x51, 0x230,
|
||||||
|
0x52, 0x220,
|
||||||
|
0x53, 0x230,
|
||||||
|
0x54, 0x230,
|
||||||
|
0xbc, 0x7,
|
||||||
|
0xcd, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page0a */
|
||||||
|
0x0a,
|
||||||
|
0x3c, 0x7,
|
||||||
|
0x4d, 0x9,
|
||||||
|
0xbc, 0x7,
|
||||||
|
0xcd, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page0b */
|
||||||
|
0x0b,
|
||||||
|
0x3c, 0x7,
|
||||||
|
0x4d, 0x9,
|
||||||
|
0xcd, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page0c */
|
||||||
|
0x0c,
|
||||||
|
0x4d, 0x9,
|
||||||
|
0x55, 0x84,
|
||||||
|
0x56, 0x91,
|
||||||
|
0xcd, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page0d */
|
||||||
|
0x0d,
|
||||||
|
0x4d, 0x9,
|
||||||
|
0xca, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page0e */
|
||||||
|
0x0e,
|
||||||
|
0x38, 0x103,
|
||||||
|
0x39, 0x103,
|
||||||
|
0x3a, 0x9,
|
||||||
|
0x48, 0x107,
|
||||||
|
0x49, 0x107,
|
||||||
|
0x4a, 0x107,
|
||||||
|
0x4b, 0x107,
|
||||||
|
0xb8, 0x118,
|
||||||
|
0xb9, 0x118,
|
||||||
|
0xc8, 0x122,
|
||||||
|
0xc9, 0x122,
|
||||||
|
0xca, 0x122,
|
||||||
|
0xcb, 0x122,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page0f */
|
||||||
|
0x0f,
|
||||||
|
0x18, 0x220,
|
||||||
|
0x19, 0x220,
|
||||||
|
0x35, 0x220,
|
||||||
|
0x37, 0x220,
|
||||||
|
0x39, 0x216,
|
||||||
|
0x71, 0x129,
|
||||||
|
0x72, 0x130,
|
||||||
|
0x74, 0x132,
|
||||||
|
0x7a, 0x130,
|
||||||
|
0x7b, 0x130,
|
||||||
|
0x7c, 0x130,
|
||||||
|
0x7d, 0x130,
|
||||||
|
0x80, 0x130,
|
||||||
|
0x82, 0x230,
|
||||||
|
0x83, 0x230,
|
||||||
|
0x84, 0x9,
|
||||||
|
0x86, 0x230,
|
||||||
|
0x87, 0x230,
|
||||||
|
0xc6, 0x220,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page10 */
|
||||||
|
0x10,
|
||||||
|
0x37, 0x7,
|
||||||
|
0x39, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page17 */
|
||||||
|
0x17,
|
||||||
|
0x14, 0x9,
|
||||||
|
0x34, 0x9,
|
||||||
|
0xd2, 0x9,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page18 */
|
||||||
|
0x18,
|
||||||
|
0xa9, 0x228,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page20 */
|
||||||
|
0x20,
|
||||||
|
0xd0, 0x230,
|
||||||
|
0xd1, 0x230,
|
||||||
|
0xd2, 0x1,
|
||||||
|
0xd3, 0x1,
|
||||||
|
0xd4, 0x230,
|
||||||
|
0xd5, 0x230,
|
||||||
|
0xd6, 0x230,
|
||||||
|
0xd7, 0x230,
|
||||||
|
0xd8, 0x1,
|
||||||
|
0xd9, 0x1,
|
||||||
|
0xda, 0x1,
|
||||||
|
0xdb, 0x230,
|
||||||
|
0xdc, 0x230,
|
||||||
|
0xe1, 0x230,
|
||||||
|
0xe5, 0x1,
|
||||||
|
0xe6, 0x1,
|
||||||
|
0xe7, 0x230,
|
||||||
|
0xe8, 0x220,
|
||||||
|
0xe9, 0x230,
|
||||||
|
0xea, 0x1,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* page30 */
|
||||||
|
0x30,
|
||||||
|
0x2a, 0x218,
|
||||||
|
0x2b, 0x228,
|
||||||
|
0x2c, 0x232,
|
||||||
|
0x2d, 0x222,
|
||||||
|
0x2e, 0x224,
|
||||||
|
0x2f, 0x224,
|
||||||
|
0x99, 0x8,
|
||||||
|
0x9a, 0x8,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* pagefb */
|
||||||
|
0xfb,
|
||||||
|
0x1e, 0x26,
|
||||||
|
0x00,
|
||||||
|
|
||||||
|
/* pagefe */
|
||||||
|
0xfe,
|
||||||
|
0x20, 0x230,
|
||||||
|
0x21, 0x230,
|
||||||
|
0x22, 0x230,
|
||||||
|
0x23, 0x230,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t *hfsplus_class_pages[256];
|
||||||
|
|
||||||
|
static uint16_t class_pages[19][256];
|
||||||
|
|
||||||
|
void make_hfsplus_class_pages()
|
||||||
|
{
|
||||||
|
int page_idx = -1, char_idx, i;
|
||||||
|
uint16_t *rpt, *page_pt;
|
||||||
|
int page_count = 0;
|
||||||
|
|
||||||
|
memset(class_pages, 0, 19 * 256);
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
hfsplus_class_pages[i] = NULL;
|
||||||
|
|
||||||
|
rpt = (uint16_t *) class_page_data;
|
||||||
|
page_pt = (uint16_t *) class_pages;
|
||||||
|
while (1) {
|
||||||
|
if (*rpt <= page_idx)
|
||||||
|
break;
|
||||||
|
page_count++;
|
||||||
|
page_idx = *(rpt++);
|
||||||
|
char_idx = -1;
|
||||||
|
while (1) {
|
||||||
|
if(*rpt <= char_idx)
|
||||||
|
break;
|
||||||
|
char_idx = *(rpt++);
|
||||||
|
page_pt[char_idx] = *(rpt++);
|
||||||
|
}
|
||||||
|
rpt++;
|
||||||
|
hfsplus_class_pages[page_idx] = class_pages[page_count - 1];
|
||||||
|
page_pt += 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1090
libisofs/hfsplus_decompose.c
Normal file
1090
libisofs/hfsplus_decompose.c
Normal file
File diff suppressed because it is too large
Load Diff
219
libisofs/image.c
219
libisofs/image.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -78,11 +78,13 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
img->volset_id = strdup(name);
|
img->volset_id = strdup(name);
|
||||||
img->volume_id = strdup(name);
|
img->volume_id = strdup(name);
|
||||||
}
|
}
|
||||||
|
memset(img->application_use, 0, 512);
|
||||||
img->system_area_data = NULL;
|
img->system_area_data = NULL;
|
||||||
img->system_area_options = 0;
|
img->system_area_options = 0;
|
||||||
img->num_mips_boot_files = 0;
|
img->num_mips_boot_files = 0;
|
||||||
for (i = 0; i < 15; i++)
|
for (i = 0; i < 15; i++)
|
||||||
img->mips_boot_file_paths[i] = NULL;
|
img->mips_boot_file_paths[i] = NULL;
|
||||||
|
img->sparc_core_node = NULL;
|
||||||
img->builder_ignore_acl = 1;
|
img->builder_ignore_acl = 1;
|
||||||
img->builder_ignore_ea = 1;
|
img->builder_ignore_ea = 1;
|
||||||
img->inode_counter = 0;
|
img->inode_counter = 0;
|
||||||
@ -93,6 +95,9 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
img->checksum_idx_count = 0;
|
img->checksum_idx_count = 0;
|
||||||
img->checksum_array = NULL;
|
img->checksum_array = NULL;
|
||||||
img->generator_is_running = 0;
|
img->generator_is_running = 0;
|
||||||
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||||
|
img->hfsplus_blessed[i] = NULL;
|
||||||
|
|
||||||
*image = img;
|
*image = img;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -112,25 +117,29 @@ void iso_image_ref(IsoImage *image)
|
|||||||
*/
|
*/
|
||||||
void iso_image_unref(IsoImage *image)
|
void iso_image_unref(IsoImage *image)
|
||||||
{
|
{
|
||||||
if (--image->refcount == 0) {
|
int nexcl, i;
|
||||||
int nexcl;
|
|
||||||
|
|
||||||
|
if (--image->refcount == 0) {
|
||||||
/* we need to free the image */
|
/* we need to free the image */
|
||||||
|
|
||||||
if (image->user_data_free != NULL) {
|
if (image->user_data_free != NULL) {
|
||||||
/* free attached data */
|
/* free attached data */
|
||||||
image->user_data_free(image->user_data);
|
image->user_data_free(image->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (nexcl = 0; nexcl < image->nexcludes; ++nexcl) {
|
for (nexcl = 0; nexcl < image->nexcludes; ++nexcl) {
|
||||||
free(image->excludes[nexcl]);
|
free(image->excludes[nexcl]);
|
||||||
}
|
}
|
||||||
free(image->excludes);
|
free(image->excludes);
|
||||||
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||||
|
if (image->hfsplus_blessed[i] != NULL)
|
||||||
|
iso_node_unref(image->hfsplus_blessed[i]);
|
||||||
iso_node_unref((IsoNode*)image->root);
|
iso_node_unref((IsoNode*)image->root);
|
||||||
iso_node_builder_unref(image->builder);
|
iso_node_builder_unref(image->builder);
|
||||||
iso_filesystem_unref(image->fs);
|
iso_filesystem_unref(image->fs);
|
||||||
el_torito_boot_catalog_free(image->bootcat);
|
el_torito_boot_catalog_free(image->bootcat);
|
||||||
iso_image_give_up_mips_boot(image, 0);
|
iso_image_give_up_mips_boot(image, 0);
|
||||||
|
if (image->sparc_core_node != NULL)
|
||||||
|
iso_node_unref((IsoNode *) image->sparc_core_node);
|
||||||
free(image->volset_id);
|
free(image->volset_id);
|
||||||
free(image->volume_id);
|
free(image->volume_id);
|
||||||
free(image->publisher_id);
|
free(image->publisher_id);
|
||||||
@ -140,6 +149,10 @@ void iso_image_unref(IsoImage *image)
|
|||||||
free(image->copyright_file_id);
|
free(image->copyright_file_id);
|
||||||
free(image->abstract_file_id);
|
free(image->abstract_file_id);
|
||||||
free(image->biblio_file_id);
|
free(image->biblio_file_id);
|
||||||
|
free(image->creation_time);
|
||||||
|
free(image->modification_time);
|
||||||
|
free(image->expiration_time);
|
||||||
|
free(image->effective_time);
|
||||||
if (image->used_inodes != NULL)
|
if (image->used_inodes != NULL)
|
||||||
free(image->used_inodes);
|
free(image->used_inodes);
|
||||||
if (image->system_area_data != NULL)
|
if (image->system_area_data != NULL)
|
||||||
@ -330,6 +343,50 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image)
|
|||||||
return image->biblio_file_id;
|
return image->biblio_file_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_image_set_pvd_times(IsoImage *image,
|
||||||
|
char *creation_time, char *modification_time,
|
||||||
|
char *expiration_time, char *effective_time)
|
||||||
|
{
|
||||||
|
if (creation_time == NULL || modification_time == NULL ||
|
||||||
|
expiration_time == NULL || effective_time == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
image->creation_time = strdup(creation_time);
|
||||||
|
image->modification_time = strdup(modification_time);
|
||||||
|
image->expiration_time = strdup(expiration_time);
|
||||||
|
image->effective_time = strdup(effective_time);
|
||||||
|
if (image->creation_time == NULL || image->modification_time == NULL ||
|
||||||
|
image->expiration_time == NULL || image->effective_time == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_image_get_pvd_times(IsoImage *image,
|
||||||
|
char **creation_time, char **modification_time,
|
||||||
|
char **expiration_time, char **effective_time)
|
||||||
|
{
|
||||||
|
if (image->creation_time == NULL || image->modification_time == NULL ||
|
||||||
|
image->expiration_time == NULL || image->effective_time == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
*creation_time = image->creation_time;
|
||||||
|
*modification_time = image->modification_time;
|
||||||
|
*expiration_time = image->expiration_time;
|
||||||
|
*effective_time = image->effective_time;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
|
||||||
|
int count)
|
||||||
|
{
|
||||||
|
if (count < 0)
|
||||||
|
count= 0;
|
||||||
|
else if(count > 512)
|
||||||
|
count= 512;
|
||||||
|
if (count > 0)
|
||||||
|
memcpy(image->application_use, app_use_data, count);
|
||||||
|
if (count < 512)
|
||||||
|
memset(image->application_use + count, 0, 512 - count);
|
||||||
|
}
|
||||||
|
|
||||||
int iso_image_get_msg_id(IsoImage *image)
|
int iso_image_get_msg_id(IsoImage *image)
|
||||||
{
|
{
|
||||||
return image->id;
|
return image->id;
|
||||||
@ -349,21 +406,74 @@ static
|
|||||||
int dir_update_size(IsoImage *image, IsoDir *dir)
|
int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||||
{
|
{
|
||||||
IsoNode *pos;
|
IsoNode *pos;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifdef Libisofs_update_sizes_abortablE
|
||||||
|
char *path= NULL;
|
||||||
|
IsoStream *base_stream;
|
||||||
|
int cancel_ret, ret;
|
||||||
|
uint32_t lba;
|
||||||
|
#endif
|
||||||
|
|
||||||
pos = dir->children;
|
pos = dir->children;
|
||||||
while (pos) {
|
while (pos) {
|
||||||
int ret = 1;
|
|
||||||
if (pos->type == LIBISO_FILE) {
|
if (pos->type == LIBISO_FILE) {
|
||||||
ret = iso_stream_update_size(ISO_FILE(pos)->stream);
|
ret = iso_stream_update_size(ISO_FILE(pos)->stream);
|
||||||
} else if (pos->type == LIBISO_DIR) {
|
} else if (pos->type == LIBISO_DIR) {
|
||||||
/* recurse */
|
/* recurse */
|
||||||
ret = dir_update_size(image, ISO_DIR(pos));
|
ret = dir_update_size(image, ISO_DIR(pos));
|
||||||
|
|
||||||
|
#ifdef Libisofs_update_sizes_abortablE
|
||||||
|
if (ret == ISO_CANCELED)
|
||||||
|
return ret; /* Message already issued by dir_update_size */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_update_sizes_abortablE
|
||||||
|
|
||||||
|
/* This would report error and abort according to severity threshold.
|
||||||
|
But it is desirable to let the update_size crawler continue
|
||||||
|
its work after e.g. a file has vanished from hard disk.
|
||||||
|
So normally this macro case should be disabled.
|
||||||
|
*/
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = iso_msg_submit(image->id, ret, 0, NULL);
|
cancel_ret = iso_msg_submit(image->id, ret, 0, NULL);
|
||||||
if (ret < 0) {
|
path = iso_tree_get_node_path(pos);
|
||||||
return ret; /* cancel due error threshold */
|
if (path != NULL) {
|
||||||
|
iso_msg_submit(image->id, ret, 0,
|
||||||
|
"ISO path : %s", path);
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
/* Report source path with streams which do not come from
|
||||||
|
the loaded ISO filesystem */
|
||||||
|
if (pos->type == LIBISO_FILE &&
|
||||||
|
iso_node_get_old_image_lba(pos, &lba, 0) == 0) {
|
||||||
|
base_stream = iso_stream_get_input_stream(
|
||||||
|
ISO_FILE(pos)->stream, 1);
|
||||||
|
if (base_stream == NULL)
|
||||||
|
base_stream = ISO_FILE(pos)->stream;
|
||||||
|
path = iso_stream_get_source_path(base_stream, 0);
|
||||||
|
if (path != NULL) {
|
||||||
|
iso_msg_submit(image->id, ret, 0,
|
||||||
|
"Local path: %s", path);
|
||||||
|
free(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cancel_ret < 0)
|
||||||
|
return cancel_ret; /* cancel due error threshold */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
ret = 1; /* ignore error */
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_update_sizes_abortablE */
|
||||||
|
|
||||||
pos = pos->next;
|
pos = pos->next;
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -657,3 +767,94 @@ int iso_image_give_up_mips_boot(IsoImage *image, int flag)
|
|||||||
image->num_mips_boot_files = 0;
|
image->num_mips_boot_files = 0;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unset_blessing(IsoImage *img, unsigned int idx)
|
||||||
|
{
|
||||||
|
if (img->hfsplus_blessed[idx] != NULL)
|
||||||
|
iso_node_unref(img->hfsplus_blessed[idx]);
|
||||||
|
img->hfsplus_blessed[idx] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_hfsplus_bless(IsoImage *img, enum IsoHfsplusBlessings blessing,
|
||||||
|
IsoNode *node, int flag)
|
||||||
|
{
|
||||||
|
unsigned int i, ok = 0;
|
||||||
|
|
||||||
|
if (flag & 2) {
|
||||||
|
/* Delete any blessing */
|
||||||
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++) {
|
||||||
|
if (img->hfsplus_blessed[i] == node || node == NULL) {
|
||||||
|
unset_blessing(img, i);
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
if (blessing == ISO_HFSPLUS_BLESS_MAX)
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
if (flag & 1) {
|
||||||
|
/* Delete a particular blessing */
|
||||||
|
if (img->hfsplus_blessed[blessing] == node || node == NULL) {
|
||||||
|
unset_blessing(img, (unsigned int) blessing);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
unset_blessing(img, (unsigned int) blessing);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No two hats on one node */
|
||||||
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX && node != NULL; i++)
|
||||||
|
if (i != blessing && img->hfsplus_blessed[i] == node)
|
||||||
|
return 0;
|
||||||
|
/* Enforce correct file type */
|
||||||
|
if (blessing == ISO_HFSPLUS_BLESS_INTEL_BOOTFILE) {
|
||||||
|
if (node->type != LIBISO_FILE)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (node->type != LIBISO_DIR)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset_blessing(img, (unsigned int) blessing);
|
||||||
|
img->hfsplus_blessed[blessing] = node;
|
||||||
|
if (node != NULL)
|
||||||
|
iso_node_ref(node);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
|
||||||
|
int *bless_max, int flag)
|
||||||
|
{
|
||||||
|
*blessed_nodes = img->hfsplus_blessed;
|
||||||
|
*bless_max = ISO_HFSPLUS_BLESS_MAX;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag)
|
||||||
|
{
|
||||||
|
if (img->sparc_core_node != NULL)
|
||||||
|
iso_node_unref((IsoNode *) img->sparc_core_node);
|
||||||
|
img->sparc_core_node = sparc_core;
|
||||||
|
if (sparc_core != NULL)
|
||||||
|
iso_node_ref((IsoNode *) sparc_core);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
|
||||||
|
{
|
||||||
|
*sparc_core = img->sparc_core_node;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -49,6 +49,11 @@ struct Iso_Image
|
|||||||
char *copyright_file_id;
|
char *copyright_file_id;
|
||||||
char *abstract_file_id;
|
char *abstract_file_id;
|
||||||
char *biblio_file_id;
|
char *biblio_file_id;
|
||||||
|
char *creation_time;
|
||||||
|
char *modification_time;
|
||||||
|
char *expiration_time;
|
||||||
|
char *effective_time;
|
||||||
|
char application_use[512];
|
||||||
|
|
||||||
/* el-torito boot catalog */
|
/* el-torito boot catalog */
|
||||||
struct el_torito_boot_catalog *bootcat;
|
struct el_torito_boot_catalog *bootcat;
|
||||||
@ -65,6 +70,10 @@ struct Iso_Image
|
|||||||
int num_mips_boot_files;
|
int num_mips_boot_files;
|
||||||
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
|
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
|
||||||
|
|
||||||
|
/* A data file of which the position and size shall be written after
|
||||||
|
a SUN Disk Label.
|
||||||
|
*/
|
||||||
|
IsoFile *sparc_core_node;
|
||||||
|
|
||||||
/* image identifier, for message origin identifier */
|
/* image identifier, for message origin identifier */
|
||||||
int id;
|
int id;
|
||||||
@ -180,6 +189,13 @@ struct Iso_Image
|
|||||||
*/
|
*/
|
||||||
int generator_is_running;
|
int generator_is_running;
|
||||||
|
|
||||||
|
/* Pointers to directories or files which shall be get a HFS+ blessing.
|
||||||
|
* libisofs/hfsplus.c et.al. will compare these pointers
|
||||||
|
* with the ->node pointer of Ecma119Nodes.
|
||||||
|
* See libisofs.h
|
||||||
|
*/
|
||||||
|
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -227,4 +243,8 @@ int iso_image_set_checksums(IsoImage *image, char *checksum_array,
|
|||||||
uint32_t idx_count, int flag);
|
uint32_t idx_count, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
int iso_image_set_pvd_times(IsoImage *image,
|
||||||
|
char *creation_time, char *modification_time,
|
||||||
|
char *expiration_time, char *effective_time);
|
||||||
|
|
||||||
#endif /*LIBISO_IMAGE_H_*/
|
#endif /*LIBISO_IMAGE_H_*/
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "filesrc.h"
|
#include "filesrc.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -307,7 +308,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
int ret;
|
int ret;
|
||||||
int i, nchildren;
|
int i, nchildren;
|
||||||
Iso1999Node **children;
|
Iso1999Node **children;
|
||||||
IsoHTable *table;
|
IsoHTable *table = NULL;
|
||||||
int need_sort = 0;
|
int need_sort = 0;
|
||||||
char *full_name = NULL, *tmp = NULL;
|
char *full_name = NULL, *tmp = NULL;
|
||||||
|
|
||||||
@ -801,10 +802,8 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
|
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
|
||||||
strncpy_pad((char*)vol.bibliographic_file_id, biblio_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);
|
ecma119_set_voldescr_times(writer, (struct ecma119_pri_vol_desc *) &vol);
|
||||||
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
|
vol.file_structure_version[0] = 2;
|
||||||
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
|
|
||||||
vol.file_structure_version[0] = 1;
|
|
||||||
|
|
||||||
free(vol_id);
|
free(vol_id);
|
||||||
free(volset_id);
|
free(volset_id);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -332,11 +333,12 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
|
|||||||
|
|
||||||
if (ext[0] != (uint16_t)0) {
|
if (ext[0] != (uint16_t)0) {
|
||||||
size_t extlen = ucslen(ext);
|
size_t extlen = ucslen(ext);
|
||||||
dest[pos++] = (uint16_t)0x2E00; /* '.' in big endian UCS */
|
iso_msb((uint8_t *) (dest + pos), 0x002E, 2); /* '.' in UCS */
|
||||||
|
pos++;
|
||||||
ucsncpy(dest + pos, ext, extlen);
|
ucsncpy(dest + pos, ext, extlen);
|
||||||
pos += extlen;
|
pos += extlen;
|
||||||
}
|
}
|
||||||
dest[pos] = (uint16_t)0;
|
iso_msb((uint8_t *) (dest + pos), 0, 2);
|
||||||
free(ucsnumber);
|
free(ucsnumber);
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -347,7 +349,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
int ret;
|
int ret;
|
||||||
int i, nchildren, maxchar = 64;
|
int i, nchildren, maxchar = 64;
|
||||||
JolietNode **children;
|
JolietNode **children;
|
||||||
IsoHTable *table;
|
IsoHTable *table = NULL;
|
||||||
int need_sort = 0;
|
int need_sort = 0;
|
||||||
uint16_t *full_name = NULL;
|
uint16_t *full_name = NULL;
|
||||||
uint16_t *tmp = NULL;
|
uint16_t *tmp = NULL;
|
||||||
@ -911,9 +913,7 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
ucsncpy_pad((uint16_t*)vol.abstract_file_id, abstract_file_id, 37);
|
ucsncpy_pad((uint16_t*)vol.abstract_file_id, abstract_file_id, 37);
|
||||||
ucsncpy_pad((uint16_t*)vol.bibliographic_file_id, biblio_file_id, 37);
|
ucsncpy_pad((uint16_t*)vol.bibliographic_file_id, biblio_file_id, 37);
|
||||||
|
|
||||||
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
|
ecma119_set_voldescr_times(writer, (struct ecma119_pri_vol_desc *) &vol);
|
||||||
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
|
|
||||||
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
|
|
||||||
vol.file_structure_version[0] = 1;
|
vol.file_structure_version[0] = 1;
|
||||||
|
|
||||||
free(vol_id);
|
free(vol_id);
|
||||||
|
@ -288,7 +288,7 @@ int libiso_msgs__sev_to_text(int severity, char **severity_name,
|
|||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
if(flag&1) {
|
if(flag&1) {
|
||||||
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL";
|
*severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER";
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
*severity_name= "";
|
*severity_name= "";
|
||||||
|
@ -316,7 +316,7 @@ int libiso_msgs_submit(struct libiso_msgs *m, int origin, int error_code,
|
|||||||
|
|
||||||
/** Convert a registered severity number into a severity name
|
/** Convert a registered severity number into a severity name
|
||||||
@param flag Bitfield for control purposes:
|
@param flag Bitfield for control purposes:
|
||||||
bit0= list all severity names in a newline separated string
|
bit0= list all severity names in a blank separated string
|
||||||
@return >0 success, <=0 failure
|
@return >0 success, <=0 failure
|
||||||
*/
|
*/
|
||||||
int libiso_msgs__sev_to_text(int severity, char **severity_name,
|
int libiso_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||||
* Copyright (c) 2009-2012 Thomas Schmitt
|
* Copyright (c) 2009-2013 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -83,8 +83,8 @@
|
|||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
*/
|
*/
|
||||||
#define iso_lib_header_version_major 1
|
#define iso_lib_header_version_major 1
|
||||||
#define iso_lib_header_version_minor 2
|
#define iso_lib_header_version_minor 3
|
||||||
#define iso_lib_header_version_micro 2
|
#define iso_lib_header_version_micro 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get version of the libisofs library at runtime.
|
* Get version of the libisofs library at runtime.
|
||||||
@ -295,6 +295,16 @@ enum IsoHideNodeFlag {
|
|||||||
/** Hide the node in the ISO-9660:1999 tree, if that format is enabled */
|
/** Hide the node in the ISO-9660:1999 tree, if that format is enabled */
|
||||||
LIBISO_HIDE_ON_1999 = 1 << 2,
|
LIBISO_HIDE_ON_1999 = 1 << 2,
|
||||||
|
|
||||||
|
/** Hide the node in the HFS+ tree, if that format is enabled.
|
||||||
|
@since 1.2.4
|
||||||
|
*/
|
||||||
|
LIBISO_HIDE_ON_HFSPLUS = 1 << 4,
|
||||||
|
|
||||||
|
/** Hide the node in the FAT tree, if that format is enabled.
|
||||||
|
@since 1.2.4
|
||||||
|
*/
|
||||||
|
LIBISO_HIDE_ON_FAT = 1 << 5,
|
||||||
|
|
||||||
/** With IsoNode and IsoBoot: Write data content even if the node is
|
/** With IsoNode and IsoBoot: Write data content even if the node is
|
||||||
* not visible in any tree.
|
* not visible in any tree.
|
||||||
* With directory nodes : Write data content of IsoNode and IsoBoot
|
* With directory nodes : Write data content of IsoNode and IsoBoot
|
||||||
@ -1391,6 +1401,96 @@ int iso_write_opts_set_rockridge(IsoWriteOpts *opts, int enable);
|
|||||||
*/
|
*/
|
||||||
int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable);
|
int iso_write_opts_set_joliet(IsoWriteOpts *opts, int enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to add a HFS+ filesystem to the image which points to the same
|
||||||
|
* file content as the other directory trees.
|
||||||
|
* It will get marked by an Apple Partition Map in the System Area of the ISO
|
||||||
|
* image. This may collide with data submitted by
|
||||||
|
* iso_write_opts_set_system_area()
|
||||||
|
* and with settings made by
|
||||||
|
* el_torito_set_isolinux_options()
|
||||||
|
* The first 8 bytes of the System Area get overwritten by
|
||||||
|
* {0x45, 0x52, 0x08 0x00, 0xeb, 0x02, 0xff, 0xff}
|
||||||
|
* which can be executed as x86 machine code without negative effects.
|
||||||
|
* So if an MBR gets combined with this feature, then its first 8 bytes
|
||||||
|
* should contain no essential commands.
|
||||||
|
* The next blocks of 2 KiB in the System Area will be occupied by APM entries.
|
||||||
|
* The first one covers the part of the ISO image before the HFS+ filesystem
|
||||||
|
* metadata. The second one marks the range from HFS+ metadata to the end
|
||||||
|
* of file content data. If more ISO image data follow, then a third partition
|
||||||
|
* entry gets produced. Other features of libisofs might cause the need for
|
||||||
|
* more APM entries.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param enable
|
||||||
|
* 1 to enable HFS+ extension, 0 to not add HFS+ metadata and APM
|
||||||
|
* @return
|
||||||
|
* 1 success, < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_hfsplus(IsoWriteOpts *opts, int enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* >>> Production of FAT32 is not implemented yet.
|
||||||
|
* >>> This call exists only as preparation for implementation.
|
||||||
|
*
|
||||||
|
* Whether to add a FAT32 filesystem to the image which points to the same
|
||||||
|
* file content as the other directory trees.
|
||||||
|
*
|
||||||
|
* >>> FAT32 is planned to get implemented in co-existence with HFS+
|
||||||
|
* >>> Describe impact on MBR
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param enable
|
||||||
|
* 1 to enable FAT32 extension, 0 to not add FAT metadata
|
||||||
|
* @return
|
||||||
|
* 1 success, < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_fat(IsoWriteOpts *opts, int enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supply a serial number for the HFS+ extension of the emerging image.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param serial_number
|
||||||
|
* 8 bytes which should be unique to the image.
|
||||||
|
* If all bytes are 0, then the serial number will be generated as
|
||||||
|
* random number by libisofs. This is the default setting.
|
||||||
|
* @return
|
||||||
|
* 1 success, < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
|
||||||
|
uint8_t serial_number[8]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the block size for Apple Partition Map and for HFS+.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param hfsp_block_size
|
||||||
|
* The allocation block size to be used by the HFS+ fileystem.
|
||||||
|
* 0, 512, or 2048
|
||||||
|
* @param hfsp_block_size
|
||||||
|
* The block size to be used for and within the Apple Partition Map.
|
||||||
|
* 0, 512, or 2048.
|
||||||
|
* Size 512 is not compatible with options which produce GPT.
|
||||||
|
* @return
|
||||||
|
* 1 success, < 0 error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
|
||||||
|
int hfsp_block_size, int apm_block_size);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to use newer ISO-9660:1999 version.
|
* Whether to use newer ISO-9660:1999 version.
|
||||||
*
|
*
|
||||||
@ -2056,30 +2156,50 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
|
|||||||
* bit2-7= System area type
|
* bit2-7= System area type
|
||||||
* 0= with bit0 or bit1: MBR
|
* 0= with bit0 or bit1: MBR
|
||||||
* else: unspecified type which will be used unaltered.
|
* else: unspecified type which will be used unaltered.
|
||||||
* @since 0.6.38
|
|
||||||
* 1= MIPS Big Endian Volume Header
|
* 1= MIPS Big Endian Volume Header
|
||||||
|
* @since 0.6.38
|
||||||
* Submit up to 15 MIPS Big Endian boot files by
|
* Submit up to 15 MIPS Big Endian boot files by
|
||||||
* iso_image_add_mips_boot_file().
|
* iso_image_add_mips_boot_file().
|
||||||
* This will overwrite the first 512 bytes of the submitted
|
* This will overwrite the first 512 bytes of the submitted
|
||||||
* data.
|
* data.
|
||||||
* 2= DEC Boot Block for MIPS Little Endian
|
* 2= DEC Boot Block for MIPS Little Endian
|
||||||
|
* @since 0.6.38
|
||||||
* The first boot file submitted by
|
* The first boot file submitted by
|
||||||
* iso_image_add_mips_boot_file() will be activated.
|
* iso_image_add_mips_boot_file() will be activated.
|
||||||
* This will overwrite the first 512 bytes of the submitted
|
* This will overwrite the first 512 bytes of the submitted
|
||||||
* data.
|
* data.
|
||||||
* @since 0.6.40
|
|
||||||
* 3= SUN Disk Label for SUN SPARC
|
* 3= SUN Disk Label for SUN SPARC
|
||||||
|
* @since 0.6.40
|
||||||
* Submit up to 7 SPARC boot images by
|
* Submit up to 7 SPARC boot images by
|
||||||
* iso_write_opts_set_partition_img() for partition numbers 2
|
* iso_write_opts_set_partition_img() for partition numbers 2
|
||||||
* to 8.
|
* to 8.
|
||||||
* This will overwrite the first 512 bytes of the submitted
|
* This will overwrite the first 512 bytes of the submitted
|
||||||
|
* data.
|
||||||
* bit8-9= Only with System area type 0 = MBR
|
* bit8-9= Only with System area type 0 = MBR
|
||||||
* @since 1.0.4
|
* @since 1.0.4
|
||||||
* Cylinder alignment mode eventually pads the image to make it
|
* Cylinder alignment mode eventually pads the image to make it
|
||||||
* end at a cylinder boundary.
|
* end at a cylinder boundary.
|
||||||
* 0 = auto (align if bit1)
|
* 0 = auto (align if bit1)
|
||||||
* 1 = always align to cylinder boundary
|
* 1 = always align to cylinder boundary
|
||||||
* 2 = never align to cylinder boundary
|
* 2 = never align to cylinder boundary
|
||||||
|
* 3 = always align, additionally pad up and align partitions
|
||||||
|
* which were appended by iso_write_opts_set_partition_img()
|
||||||
|
* @since 1.2.6
|
||||||
|
* bit10-13= System area sub type
|
||||||
|
* @since 1.2.4
|
||||||
|
* With type 0 = MBR:
|
||||||
|
* Gets overridden by bit0 and bit1.
|
||||||
|
* 0 = no particular sub type
|
||||||
|
* 1 = CHRP: A single MBR partition of type 0x96 covers the
|
||||||
|
* ISO image. Not compatible with any other feature
|
||||||
|
* which needs to have own MBR partition entries.
|
||||||
|
* bit14= Only with System area type 0 = MBR
|
||||||
|
* GRUB2 boot provisions:
|
||||||
|
* @since 1.3.0
|
||||||
|
* Patch system area at byte 92 to 99 with 512-block address + 1
|
||||||
|
* of the first boot image file. Little-endian 8-byte.
|
||||||
|
* Should be combined with options bit0.
|
||||||
|
* Will not be in effect if options bit1 is set.
|
||||||
* @param flag
|
* @param flag
|
||||||
* bit0 = invalidate any attached system area data. Same as data == NULL
|
* bit0 = invalidate any attached system area data. Same as data == NULL
|
||||||
* (This re-activates eventually loaded image System Area data.
|
* (This re-activates eventually loaded image System Area data.
|
||||||
@ -2111,7 +2231,10 @@ int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Explicitely set the four timestamps of the emerging Primary Volume
|
* Explicitely set the four timestamps of the emerging Primary Volume
|
||||||
* Descriptor. Default with all parameters is 0.
|
* Descriptor and in the volume descriptors of Joliet and ISO 9660:1999,
|
||||||
|
* if those are to be generated.
|
||||||
|
* Default with all parameters is 0.
|
||||||
|
*
|
||||||
* ECMA-119 defines them as:
|
* ECMA-119 defines them as:
|
||||||
* @param opts
|
* @param opts
|
||||||
* The option set to be manipulated.
|
* The option set to be manipulated.
|
||||||
@ -2252,6 +2375,65 @@ int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle);
|
|||||||
*/
|
*/
|
||||||
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a data file from the local filesystem into the emerging ISO image.
|
||||||
|
* Mark it by an MBR partition entry as PreP partition and also cause
|
||||||
|
* protective MBR partition entries before and after this partition.
|
||||||
|
* Vladimir Serbinenko stated aboy PreP = PowerPC Reference Platform :
|
||||||
|
* "PreP [...] refers mainly to IBM hardware. PreP boot is a partition
|
||||||
|
* containing only raw ELF and having type 0x41."
|
||||||
|
*
|
||||||
|
* This feature is only combinable with system area type 0
|
||||||
|
* and currently not combinable with ISOLINUX isohybrid production.
|
||||||
|
* It overrides --protective-msdos-label. See iso_write_opts_set_system_area().
|
||||||
|
* Only partition 4 stays available for iso_write_opts_set_partition_img().
|
||||||
|
* It is compatible with HFS+/FAT production by storing the PreP partition
|
||||||
|
* before the start of the HFS+/FAT partition.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param image_path
|
||||||
|
* File address in the local file system.
|
||||||
|
* NULL revokes production of the PreP partition.
|
||||||
|
* @param flag
|
||||||
|
* Reserved for future usage, set to 0.
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a data file from the local filesystem into the emerging ISO image.
|
||||||
|
* Mark it by an GPT partition entry as EFI System partition, and also cause
|
||||||
|
* protective GPT partition entries before and after the partition.
|
||||||
|
* GPT = Globally Unique Identifier Partition Table
|
||||||
|
*
|
||||||
|
* This feature may collide with data submitted by
|
||||||
|
* iso_write_opts_set_system_area()
|
||||||
|
* and with settings made by
|
||||||
|
* el_torito_set_isolinux_options()
|
||||||
|
* It is compatible with HFS+/FAT production by storing the EFI partition
|
||||||
|
* before the start of the HFS+/FAT partition.
|
||||||
|
* The GPT overwrites byte 0x0200 to 0x03ff of the system area and all
|
||||||
|
* further bytes above 0x0800 which are not used by an Apple Partition Map.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param image_path
|
||||||
|
* File address in the local file system.
|
||||||
|
* NULL revokes production of the EFI boot partition.
|
||||||
|
* @param flag
|
||||||
|
* Reserved for future usage, set to 0.
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
|
||||||
|
int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cause an arbitrary data file to be appended to the ISO image and to be
|
* Cause an arbitrary data file to be appended to the ISO image and to be
|
||||||
@ -2279,6 +2461,8 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
|
|||||||
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
|
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
|
||||||
* Linux Native Partition = 0x83. See fdisk command L.
|
* Linux Native Partition = 0x83. See fdisk command L.
|
||||||
* This parameter is ignored with SUN Disk Label.
|
* This parameter is ignored with SUN Disk Label.
|
||||||
|
* @param flag
|
||||||
|
* Reserved for future usage, set to 0.
|
||||||
* @return
|
* @return
|
||||||
* ISO_SUCCESS or error
|
* ISO_SUCCESS or error
|
||||||
*
|
*
|
||||||
@ -2711,7 +2895,7 @@ void iso_image_set_volset_id(IsoImage *image, const char *volset_id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the volset identifier.
|
* Get the volset identifier.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2727,7 +2911,7 @@ void iso_image_set_volume_id(IsoImage *image, const char *volume_id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the volume identifier.
|
* Get the volume identifier.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2743,7 +2927,7 @@ void iso_image_set_publisher_id(IsoImage *image, const char *publisher_id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the publisher of a image.
|
* Get the publisher of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2760,7 +2944,7 @@ void iso_image_set_data_preparer_id(IsoImage *image,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data preparer of a image.
|
* Get the data preparer of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2776,7 +2960,7 @@ void iso_image_set_system_id(IsoImage *image, const char *system_id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the system id of a image.
|
* Get the system id of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2792,7 +2976,7 @@ void iso_image_set_application_id(IsoImage *image, const char *application_id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the application id of a image.
|
* Get the application id of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2810,7 +2994,7 @@ void iso_image_set_copyright_file_id(IsoImage *image,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the copyright information of a image.
|
* Get the copyright information of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2828,7 +3012,7 @@ void iso_image_set_abstract_file_id(IsoImage *image,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the abstract information of a image.
|
* Get the abstract information of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed nor
|
||||||
* changed.
|
* changed.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -2845,13 +3029,72 @@ void iso_image_set_biblio_file_id(IsoImage *image, const char *biblio_file_id);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the biblio information of a image.
|
* Get the biblio information of a image.
|
||||||
* The returned string is owned by the image and should not be freed nor
|
* The returned string is owned by the image and must not be freed or changed.
|
||||||
* changed.
|
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
*/
|
*/
|
||||||
const char *iso_image_get_biblio_file_id(const IsoImage *image);
|
const char *iso_image_get_biblio_file_id(const IsoImage *image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill Application Use field of the Primary Volume Descriptor.
|
||||||
|
* ECMA-119 8.4.32 Application Use (BP 884 to 1395)
|
||||||
|
* "This field shall be reserved for application use. Its content
|
||||||
|
* is not specified by this Standard."
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to manipulate.
|
||||||
|
* @param app_use_data
|
||||||
|
* Up to 512 bytes of data.
|
||||||
|
* @param count
|
||||||
|
* The number of bytes in app_use_data. If the number is smaller than 512,
|
||||||
|
* then the remaining bytes will be set to 0.
|
||||||
|
* @since 1.3.2
|
||||||
|
*/
|
||||||
|
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
|
||||||
|
int count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current setting for the Application Use field of the Primary Volume
|
||||||
|
* Descriptor.
|
||||||
|
* The returned char array of 512 bytes is owned by the image and must not
|
||||||
|
* be freed or changed.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to inquire
|
||||||
|
* @since 1.3.2
|
||||||
|
*/
|
||||||
|
const char *iso_image_get_app_use(IsoImage *image);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the four timestamps from the Primary Volume Descriptor of the imported
|
||||||
|
* ISO image. The timestamps are strings which are either empty or consist
|
||||||
|
* of 17 digits of the form YYYYMMDDhhmmsscc.
|
||||||
|
* None of the returned string pointers shall be used for altering or freeing
|
||||||
|
* data. They are just for reading.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to be inquired.
|
||||||
|
* @param vol_creation_time
|
||||||
|
* Returns a pointer to the Volume Creation time:
|
||||||
|
* When "the information in the volume was created."
|
||||||
|
* @param vol_modification_time
|
||||||
|
* Returns a pointer to Volume Modification time:
|
||||||
|
* When "the information in the volume was last modified."
|
||||||
|
* @param vol_expiration_time
|
||||||
|
* Returns a pointer to Volume Expiration time:
|
||||||
|
* When "the information in the volume may be regarded as obsolete."
|
||||||
|
* @param vol_effective_time
|
||||||
|
* Returns a pointer to Volume Expiration time:
|
||||||
|
* When "the information in the volume may be used."
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
|
*
|
||||||
|
* @since 1.2.8
|
||||||
|
*/
|
||||||
|
int iso_image_get_pvd_times(IsoImage *image,
|
||||||
|
char **creation_time, char **modification_time,
|
||||||
|
char **expiration_time, char **effective_time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new set of El-Torito bootable images by adding a boot catalog
|
* Create a new set of El-Torito bootable images by adding a boot catalog
|
||||||
* and the default boot image.
|
* and the default boot image.
|
||||||
@ -2880,7 +3123,7 @@ const char *iso_image_get_biblio_file_id(const IsoImage *image);
|
|||||||
* creation time.
|
* creation time.
|
||||||
* @param boot
|
* @param boot
|
||||||
* Location where a pointer to the added boot image will be stored. That
|
* Location where a pointer to the added boot image will be stored. That
|
||||||
* object is owned by the IsoImage and should not be freed by the user,
|
* object is owned by the IsoImage and must not be freed by the user,
|
||||||
* nor dereferenced once the last reference to the IsoImage was disposed
|
* nor dereferenced once the last reference to the IsoImage was disposed
|
||||||
* via iso_image_unref(). A NULL value is allowed if you don't need a
|
* via iso_image_unref(). A NULL value is allowed if you don't need a
|
||||||
* reference to the boot image.
|
* reference to the boot image.
|
||||||
@ -2930,7 +3173,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
|||||||
* the image and catalog tree nodes. An application would want those, for
|
* the image and catalog tree nodes. An application would want those, for
|
||||||
* example, to prevent the user removing it.
|
* example, to prevent the user removing it.
|
||||||
*
|
*
|
||||||
* Both nodes are owned by libisofs and should not be freed. You can get your
|
* Both nodes are owned by libisofs and must not be freed. You can get your
|
||||||
* own ref with iso_node_ref(). You can also check if the node is already
|
* own ref with iso_node_ref(). You can also check if the node is already
|
||||||
* on the tree by getting its parent (note that when reading El-Torito info
|
* on the tree by getting its parent (note that when reading El-Torito info
|
||||||
* from a previous image, the nodes might not be on the tree even if you haven't
|
* from a previous image, the nodes might not be on the tree even if you haven't
|
||||||
@ -2942,7 +3185,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
|||||||
* The image from which to get the boot image.
|
* The image from which to get the boot image.
|
||||||
* @param boot
|
* @param boot
|
||||||
* If not NULL, it will be filled with a pointer to the boot image, if
|
* If not NULL, it will be filled with a pointer to the boot image, if
|
||||||
* any. That object is owned by the IsoImage and should not be freed by
|
* any. That object is owned by the IsoImage and must not be freed by
|
||||||
* the user, nor dereferenced once the last reference to the IsoImage was
|
* the user, nor dereferenced once the last reference to the IsoImage was
|
||||||
* disposed via iso_image_unref().
|
* disposed via iso_image_unref().
|
||||||
* @param imgnode
|
* @param imgnode
|
||||||
@ -3190,7 +3433,7 @@ int el_torito_get_bootable(ElToritoBootImage *bootimg);
|
|||||||
* the CD-ROM".
|
* the CD-ROM".
|
||||||
* Further boot images put 28 bytes into their Section Header.
|
* Further boot images put 28 bytes into their Section Header.
|
||||||
* El Torito 1.0 states that "If the BIOS understands the ID string, it
|
* 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
|
* 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
|
* of the INITIAL/DEFAULT entry." (The INITIAL/DEFAULT entry points to the
|
||||||
* first boot image.)
|
* first boot image.)
|
||||||
* @return
|
* @return
|
||||||
@ -3260,9 +3503,15 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
|
|||||||
* @param bootimg
|
* @param bootimg
|
||||||
* The image to inquire
|
* The image to inquire
|
||||||
* @param flag
|
* @param flag
|
||||||
* Reserved for future usage, set to 0.
|
* Bitfield for control purposes:
|
||||||
|
* bit0 - bit3= mode
|
||||||
|
* 0 = inquire for classic boot info table as described in man mkisofs
|
||||||
|
* @since 0.6.32
|
||||||
|
* 1 = inquire for GRUB2 boot info as of bit9 of options of
|
||||||
|
* el_torito_set_isolinux_options()
|
||||||
|
* @since 1.3.0
|
||||||
* @return
|
* @return
|
||||||
* 1 = seems to contain oot info table , 0 = quite surely not
|
* 1 = seems to contain the inquired boot info, 0 = quite surely not
|
||||||
* @since 0.6.32
|
* @since 0.6.32
|
||||||
*/
|
*/
|
||||||
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
||||||
@ -3276,30 +3525,61 @@ int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag);
|
|||||||
* @param options
|
* @param options
|
||||||
* bitmask style flag. The following values are defined:
|
* bitmask style flag. The following values are defined:
|
||||||
*
|
*
|
||||||
* bit 0 -> 1 to patch the boot info table of the boot image.
|
* bit0= Patch the boot info table of the boot image.
|
||||||
* 1 does the same as mkisofs option -boot-info-table.
|
* This does the same as mkisofs option -boot-info-table.
|
||||||
* Needed for ISOLINUX or GRUB boot images with platform ID 0.
|
* Needed for ISOLINUX or GRUB boot images with platform ID 0.
|
||||||
* The table is located at byte 8 of the boot image file.
|
* The table is located at byte 8 of the boot image file.
|
||||||
* Its size is 56 bytes.
|
* Its size is 56 bytes.
|
||||||
* The original boot image file on disk will not be modified.
|
* The original boot image file on disk will not be modified.
|
||||||
*
|
*
|
||||||
* One may use el_torito_seems_boot_info_table() for a
|
* One may use el_torito_seems_boot_info_table() for a
|
||||||
* qualified guess whether a boot info table is present in
|
* qualified guess whether a boot info table is present in
|
||||||
* the boot image. If the result is 1 then it should get bit0
|
* the boot image. If the result is 1 then it should get bit0
|
||||||
* set if its content gets copied to a new LBA.
|
* set if its content gets copied to a new LBA.
|
||||||
*
|
*
|
||||||
* bit 1 -> 1 to generate a ISOLINUX isohybrid image with MBR.
|
* bit1= Generate a ISOLINUX isohybrid image with MBR.
|
||||||
* ----------------------------------------------------------
|
* ----------------------------------------------------------
|
||||||
* @deprecated since 31 Mar 2010:
|
* @deprecated since 31 Mar 2010:
|
||||||
* The author of syslinux, H. Peter Anvin requested that this
|
* The author of syslinux, H. Peter Anvin requested that this
|
||||||
* feature shall not be used any more. He intends to cease
|
* feature shall not be used any more. He intends to cease
|
||||||
* support for the MBR template that is included in libisofs.
|
* support for the MBR template that is included in libisofs.
|
||||||
* ----------------------------------------------------------
|
* ----------------------------------------------------------
|
||||||
* A hybrid image is a boot image that boots from either
|
* A hybrid image is a boot image that boots from either
|
||||||
* CD/DVD media or from disk-like media, e.g. USB stick.
|
* CD/DVD media or from disk-like media, e.g. USB stick.
|
||||||
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
* For that you need isolinux.bin from SYSLINUX 3.72 or later.
|
||||||
* IMPORTANT: The application has to take care that the image
|
* IMPORTANT: The application has to take care that the image
|
||||||
* on media gets padded up to the next full MB.
|
* on media gets padded up to the next full MB.
|
||||||
|
* Under seiveral circumstances it might get aligned
|
||||||
|
* automatically. But there is no warranty.
|
||||||
|
* bit2-7= Mentioning in isohybrid GPT
|
||||||
|
* 0= Do not mention in GPT
|
||||||
|
* 1= Mention as Basic Data partition.
|
||||||
|
* This cannot be combined with GPT partitions as of
|
||||||
|
* iso_write_opts_set_efi_bootp()
|
||||||
|
* @since 1.2.4
|
||||||
|
* 2= Mention as HFS+ partition.
|
||||||
|
* This cannot be combined with HFS+ production by
|
||||||
|
* iso_write_opts_set_hfsplus().
|
||||||
|
* @since 1.2.4
|
||||||
|
* Primary GPT and backup GPT get written if at least one
|
||||||
|
* ElToritoBootImage shall be mentioned.
|
||||||
|
* The first three mentioned GPT partitions get mirrored in the
|
||||||
|
* the partition table of the isohybrid MBR. They get type 0xfe.
|
||||||
|
* The MBR partition entry for PC-BIOS gets type 0x00 rather
|
||||||
|
* than 0x17.
|
||||||
|
* Often it is one of the further MBR partitions which actually
|
||||||
|
* gets used by EFI.
|
||||||
|
* @since 1.2.4
|
||||||
|
* bit8= Mention in isohybrid Apple partition map
|
||||||
|
* APM get written if at least one ElToritoBootImage shall be
|
||||||
|
* mentioned. The ISOLINUX MBR must look suitable or else an error
|
||||||
|
* event will happen at image generation time.
|
||||||
|
* @since 1.2.4
|
||||||
|
* bit9= GRUB2 boot info
|
||||||
|
* Patch the boot image file at byte 1012 with the 512-block
|
||||||
|
* address + 2. Two little endian 32-bit words. Low word first.
|
||||||
|
* This is combinable with bit0.
|
||||||
|
* @since 1.3.0
|
||||||
* @param flag
|
* @param flag
|
||||||
* Reserved for future usage, set to 0.
|
* Reserved for future usage, set to 0.
|
||||||
* @return
|
* @return
|
||||||
@ -3343,7 +3623,7 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg);
|
|||||||
* @param img
|
* @param img
|
||||||
* The image to be inquired.
|
* The image to be inquired.
|
||||||
* @param data
|
* @param data
|
||||||
* A byte array of at least 32768 bytesi to take the loaded bytes.
|
* A byte array of at least 32768 bytes to take the loaded bytes.
|
||||||
* @param options
|
* @param options
|
||||||
* The option bits which will be applied if not overridden by
|
* The option bits which will be applied if not overridden by
|
||||||
* iso_write_opts_set_system_area(). See there.
|
* iso_write_opts_set_system_area(). See there.
|
||||||
@ -3407,6 +3687,41 @@ int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
|
|||||||
*/
|
*/
|
||||||
int iso_image_give_up_mips_boot(IsoImage *image, int flag);
|
int iso_image_give_up_mips_boot(IsoImage *image, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Designate a data file in the ISO image of which the position and size
|
||||||
|
* shall be written after the SUN Disk Label. The position is written as
|
||||||
|
* 64-bit big-endian number to byte position 0x228. The size is written
|
||||||
|
* as 32-bit big-endian to 0x230.
|
||||||
|
* This setting has an effect only if system area type is set to 3
|
||||||
|
* with iso_write_opts_set_system_area().
|
||||||
|
*
|
||||||
|
* @param img
|
||||||
|
* The image to be manipulated.
|
||||||
|
* @param sparc_core
|
||||||
|
* The IsoFile which shall be mentioned after the SUN Disk label.
|
||||||
|
* NULL is a permissible value. It disables this feature.
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes, unused yet, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 is success , <0 means error
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the current setting of iso_image_set_sparc_core().
|
||||||
|
*
|
||||||
|
* @param img
|
||||||
|
* The image to be inquired.
|
||||||
|
* @param sparc_core
|
||||||
|
* Will return a pointer to the IsoFile (or NULL, which is not an error)
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes, unused yet, submit 0
|
||||||
|
* @return
|
||||||
|
* 1 is success , <0 means error
|
||||||
|
* @since 1.3.0
|
||||||
|
*/
|
||||||
|
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the reference counting of the given node.
|
* Increments the reference counting of the given node.
|
||||||
@ -3512,8 +3827,8 @@ int iso_node_remove_all_xinfo(IsoNode *node, int flag);
|
|||||||
* @param proc
|
* @param proc
|
||||||
* The function pointer which serves as key
|
* The function pointer which serves as key
|
||||||
* @param data
|
* @param data
|
||||||
* Will be filled with the extended info corresponding to the given proc
|
* Will after successful call point to the xinfo data corresponding
|
||||||
* function
|
* to the given proc. This is a pointer, not a feeable data copy.
|
||||||
* @return
|
* @return
|
||||||
* 1 on success, 0 if node does not have extended info of the requested
|
* 1 on success, 0 if node does not have extended info of the requested
|
||||||
* type, < 0 on error
|
* type, < 0 on error
|
||||||
@ -3638,7 +3953,7 @@ int iso_node_set_name(IsoNode *node, const char *name);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of a node.
|
* Get the name of a node.
|
||||||
* The returned string belongs to the node and should not be modified nor
|
* The returned string belongs to the node and must not be modified nor
|
||||||
* freed. Use strdup if you really need your own copy.
|
* freed. Use strdup if you really need your own copy.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -4217,7 +4532,7 @@ int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the destination of a node.
|
* Get the destination of a node.
|
||||||
* The returned string belongs to the node and should not be modified nor
|
* The returned string belongs to the node and must not be modified nor
|
||||||
* freed. Use strdup if you really need your own copy.
|
* freed. Use strdup if you really need your own copy.
|
||||||
*
|
*
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -4868,6 +5183,37 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node);
|
|||||||
*/
|
*/
|
||||||
char *iso_tree_get_node_path(IsoNode *node);
|
char *iso_tree_get_node_path(IsoNode *node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the destination node of a symbolic link within the IsoImage.
|
||||||
|
*
|
||||||
|
* @param img
|
||||||
|
* The image wherein to try resolving the link.
|
||||||
|
* @param sym
|
||||||
|
* The symbolic link node which to resolve.
|
||||||
|
* @param res
|
||||||
|
* Will return the found destination node, in case of success.
|
||||||
|
* Call iso_node_ref() / iso_node_unref() if you intend to use the node
|
||||||
|
* over API calls which might in any event delete it.
|
||||||
|
* @param depth
|
||||||
|
* Prevents endless loops. Submit as 0.
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes. Submit 0 for now.
|
||||||
|
* @return
|
||||||
|
* 1 on success,
|
||||||
|
* < 0 on failure, especially ISO_DEEP_SYMLINK and ISO_DEAD_SYMLINK
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_tree_resolve_symlink(IsoImage *img, IsoSymlink *sym, IsoNode **res,
|
||||||
|
int *depth, int flag);
|
||||||
|
|
||||||
|
/* Maximum number link resolution steps before ISO_DEEP_SYMLINK gets
|
||||||
|
* returned by iso_tree_resolve_symlink().
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
#define LIBISO_MAX_LINK_DEPTH 100
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the reference counting of the given IsoDataSource.
|
* Increments the reference counting of the given IsoDataSource.
|
||||||
*
|
*
|
||||||
@ -5854,6 +6200,10 @@ int iso_node_lookup_attr(IsoNode *node, char *name,
|
|||||||
* I.e. those with a non-empty name which does not begin by "user."
|
* I.e. those with a non-empty name which does not begin by "user."
|
||||||
* (The empty name is always allowed and governed by bit0.) This
|
* (The empty name is always allowed and governed by bit0.) This
|
||||||
* deletes all previously existing attributes if not bit1 is set.
|
* deletes all previously existing attributes if not bit1 is set.
|
||||||
|
* bit4= Do not affect attributes from namespace "isofs".
|
||||||
|
* To be combined with bit3 for copying attributes from local
|
||||||
|
* filesystem to ISO image.
|
||||||
|
* @since 1.2.4
|
||||||
* @return
|
* @return
|
||||||
* 1 = ok
|
* 1 = ok
|
||||||
* < 0 = error
|
* < 0 = error
|
||||||
@ -6100,7 +6450,10 @@ int iso_file_remove_filter(IsoFile *file, int flag);
|
|||||||
* @param stream
|
* @param stream
|
||||||
* The eventual filter stream to be inquired.
|
* The eventual filter stream to be inquired.
|
||||||
* @param flag
|
* @param flag
|
||||||
* Bitfield for control purposes. Submit 0 for now.
|
* Bitfield for control purposes.
|
||||||
|
* bit0= Follow the chain of input streams and return the one at the
|
||||||
|
* end of the chain.
|
||||||
|
* @since 1.3.2
|
||||||
* @return
|
* @return
|
||||||
* The input stream, if one exists. Elsewise NULL.
|
* The input stream, if one exists. Elsewise NULL.
|
||||||
* No extra reference to the stream is taken by this call.
|
* No extra reference to the stream is taken by this call.
|
||||||
@ -6608,6 +6961,144 @@ int iso_md5_end(void **md5_context, char result[16]);
|
|||||||
int iso_md5_match(char first_md5[16], char second_md5[16]);
|
int iso_md5_match(char first_md5[16], char second_md5[16]);
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------- For HFS+ ------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HFS+ attributes which may be attached to IsoNode objects as data parameter
|
||||||
|
* of iso_node_add_xinfo(). As parameter proc use iso_hfsplus_xinfo_func().
|
||||||
|
* Create instances of this struct by iso_hfsplus_xinfo_new().
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
struct iso_hfsplus_xinfo_data {
|
||||||
|
|
||||||
|
/* Currently set to 0 by iso_hfsplus_xinfo_new() */
|
||||||
|
int version;
|
||||||
|
|
||||||
|
/* Attributes available with version 0.
|
||||||
|
* See: http://en.wikipedia.org/wiki/Creator_code , .../Type_code
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
uint8_t creator_code[4];
|
||||||
|
uint8_t type_code[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function that is used to mark struct iso_hfsplus_xinfo_data at IsoNodes
|
||||||
|
* and finally disposes such structs when their IsoNodes get disposed.
|
||||||
|
* Usually an application does not call this function, but only uses it as
|
||||||
|
* parameter of xinfo calls like iso_node_add_xinfo() or iso_node_get_xinfo().
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_hfsplus_xinfo_func(void *data, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance of struct iso_hfsplus_xinfo_new().
|
||||||
|
*
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes. Unused yet. Submit 0.
|
||||||
|
* @return
|
||||||
|
* A pointer to the new object
|
||||||
|
* NULL indicates failure to allocate memory
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
struct iso_hfsplus_xinfo_data *iso_hfsplus_xinfo_new(int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HFS+ blessings are relationships between HFS+ enhanced ISO images and
|
||||||
|
* particular files in such images. Except for ISO_HFSPLUS_BLESS_INTEL_BOOTFILE
|
||||||
|
* and ISO_HFSPLUS_BLESS_MAX, these files have to be directories.
|
||||||
|
* No file may have more than one blessing. Each blessing can only be issued
|
||||||
|
* to one file.
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
enum IsoHfsplusBlessings {
|
||||||
|
/* The blessing that is issued by mkisofs option -hfs-bless. */
|
||||||
|
ISO_HFSPLUS_BLESS_PPC_BOOTDIR,
|
||||||
|
|
||||||
|
/* To be applied to a data file */
|
||||||
|
ISO_HFSPLUS_BLESS_INTEL_BOOTFILE,
|
||||||
|
|
||||||
|
/* Further blessings for directories */
|
||||||
|
ISO_HFSPLUS_BLESS_SHOWFOLDER,
|
||||||
|
ISO_HFSPLUS_BLESS_OS9_FOLDER,
|
||||||
|
ISO_HFSPLUS_BLESS_OSX_FOLDER,
|
||||||
|
|
||||||
|
/* Not a blessing, but telling the number of blessings in this list */
|
||||||
|
ISO_HFSPLUS_BLESS_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issue a blessing to a particular IsoNode. If the blessing is already issued
|
||||||
|
* to some file, then it gets revoked from that one.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to manipulate.
|
||||||
|
* @param blessing
|
||||||
|
* The kind of blessing to be issued.
|
||||||
|
* @param node
|
||||||
|
* The file that shall be blessed. It must actually be an IsoDir or
|
||||||
|
* IsoFile as is appropriate for the kind of blessing. (See above enum.)
|
||||||
|
* The node may not yet bear a blessing other than the desired one.
|
||||||
|
* If node is NULL, then the blessing will be revoked from any node
|
||||||
|
* which bears it.
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes.
|
||||||
|
* bit0= Revoke blessing if node != NULL bears it.
|
||||||
|
* bit1= Revoke any blessing of the node, regardless of parameter
|
||||||
|
* blessing. If node is NULL, then revoke all blessings in
|
||||||
|
* the image.
|
||||||
|
* @return
|
||||||
|
* 1 means successful blessing or revokation of an existing blessing.
|
||||||
|
* 0 means the node already bears another blessing, or is of wrong type,
|
||||||
|
* or that the node was not blessed and revokation was desired.
|
||||||
|
* <0 is one of the listed error codes.
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_image_hfsplus_bless(IsoImage *img, enum IsoHfsplusBlessings blessing,
|
||||||
|
IsoNode *node, int flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the array of nodes which are currently blessed.
|
||||||
|
* Array indice correspond to enum IsoHfsplusBlessings.
|
||||||
|
* Array element value NULL means that no node bears that blessing.
|
||||||
|
*
|
||||||
|
* Several usage restrictions apply. See parameter blessed_nodes.
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
* The image to inquire.
|
||||||
|
* @param blessed_nodes
|
||||||
|
* Will return a pointer to an internal node array of image.
|
||||||
|
* This pointer is valid only as long as image exists and only until
|
||||||
|
* iso_image_hfsplus_bless() gets used to manipulate the blessings.
|
||||||
|
* Do not free() this array. Do not alter the content of the array
|
||||||
|
* directly, but rather use iso_image_hfsplus_bless() and re-inquire
|
||||||
|
* by iso_image_hfsplus_get_blessed().
|
||||||
|
* This call does not impose an extra reference on the nodes in the
|
||||||
|
* array. So do not iso_node_unref() them.
|
||||||
|
* Nodes listed here are not necessarily grafted into the tree of
|
||||||
|
* the IsoImage.
|
||||||
|
* @param bless_max
|
||||||
|
* Will return the number of elements in the array.
|
||||||
|
* It is unlikely but not outruled that it will be larger than
|
||||||
|
* ISO_HFSPLUS_BLESS_MAX in this libisofs.h file.
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes. Submit 0.
|
||||||
|
* @return
|
||||||
|
* 1 means success, <0 means error
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
|
||||||
|
int *bless_max, int flag);
|
||||||
|
|
||||||
|
|
||||||
/************ Error codes and return values for libisofs ********************/
|
/************ Error codes and return values for libisofs ********************/
|
||||||
|
|
||||||
/** successfully execution */
|
/** successfully execution */
|
||||||
@ -6843,7 +7334,6 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
(FAILURE, HIGH, -343) */
|
(FAILURE, HIGH, -343) */
|
||||||
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
|
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
|
||||||
|
|
||||||
|
|
||||||
/** Too many references on a single IsoExternalFilterCommand
|
/** Too many references on a single IsoExternalFilterCommand
|
||||||
(FAILURE, HIGH, -344) */
|
(FAILURE, HIGH, -344) */
|
||||||
#define ISO_EXTF_TOO_OFTEN 0xE830FEA8
|
#define ISO_EXTF_TOO_OFTEN 0xE830FEA8
|
||||||
@ -6969,7 +7459,7 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
/** Cannot open data file for appended partition (FAILURE, HIGH, -370) */
|
/** Cannot open data file for appended partition (FAILURE, HIGH, -370) */
|
||||||
#define ISO_BAD_PARTITION_FILE 0xE830FE8E
|
#define ISO_BAD_PARTITION_FILE 0xE830FE8E
|
||||||
|
|
||||||
/** May not combine appended partition with non-MBR system area
|
/** May not combine MBR partition with non-MBR system area
|
||||||
(FAILURE, HIGH, -371) */
|
(FAILURE, HIGH, -371) */
|
||||||
#define ISO_NON_MBR_SYS_AREA 0xE830FE8D
|
#define ISO_NON_MBR_SYS_AREA 0xE830FE8D
|
||||||
|
|
||||||
@ -7004,15 +7494,61 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
#define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84
|
#define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84
|
||||||
|
|
||||||
/** ACL text contains multiple entries of user::, group::, other::
|
/** ACL text contains multiple entries of user::, group::, other::
|
||||||
(FAILURE, HIGH, -379) */
|
(FAILURE, HIGH, -381) */
|
||||||
#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83
|
#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83
|
||||||
|
|
||||||
|
/** File sections do not form consecutive array of blocks
|
||||||
|
(FAILURE, HIGH, -382) */
|
||||||
|
#define ISO_SECT_SCATTERED 0xE830FE82
|
||||||
|
|
||||||
|
/** Too many Apple Partition Map entries requested (FAILURE, HIGH, -383) */
|
||||||
|
#define ISO_BOOT_TOO_MANY_APM 0xE830FE81
|
||||||
|
|
||||||
|
/** Overlapping Apple Partition Map entries requested (FAILURE, HIGH, -384) */
|
||||||
|
#define ISO_BOOT_APM_OVERLAP 0xE830FE80
|
||||||
|
|
||||||
|
/** Too many GPT entries requested (FAILURE, HIGH, -385) */
|
||||||
|
#define ISO_BOOT_TOO_MANY_GPT 0xE830FE7F
|
||||||
|
|
||||||
|
/** Overlapping GPT entries requested (FAILURE, HIGH, -386) */
|
||||||
|
#define ISO_BOOT_GPT_OVERLAP 0xE830FE7E
|
||||||
|
|
||||||
|
/** Too many MBR partition entries requested (FAILURE, HIGH, -387) */
|
||||||
|
#define ISO_BOOT_TOO_MANY_MBR 0xE830FE7D
|
||||||
|
|
||||||
|
/** Overlapping MBR partition entries requested (FAILURE, HIGH, -388) */
|
||||||
|
#define ISO_BOOT_MBR_OVERLAP 0xE830FE7C
|
||||||
|
|
||||||
|
/** Attempt to use an MBR partition entry twice (FAILURE, HIGH, -389) */
|
||||||
|
#define ISO_BOOT_MBR_COLLISION 0xE830FE7B
|
||||||
|
|
||||||
|
/** No suitable El Torito EFI boot image for exposure as GPT partition
|
||||||
|
(FAILURE, HIGH, -390) */
|
||||||
|
#define ISO_BOOT_NO_EFI_ELTO 0xE830FE7A
|
||||||
|
|
||||||
|
/** Not a supported HFS+ or APM block size (FAILURE, HIGH, -391) */
|
||||||
|
#define ISO_BOOT_HFSP_BAD_BSIZE 0xE830FE79
|
||||||
|
|
||||||
|
/** APM block size prevents coexistence with GPT (FAILURE, HIGH, -392) */
|
||||||
|
#define ISO_BOOT_APM_GPT_BSIZE 0xE830FE78
|
||||||
|
|
||||||
|
/** Name collision in HFS+, mangling not possible (FAILURE, HIGH, -393) */
|
||||||
|
#define ISO_HFSP_NO_MANGLE 0xE830FE77
|
||||||
|
|
||||||
|
/** Symbolic link cannot be resolved (FAILURE, HIGH, -394) */
|
||||||
|
#define ISO_DEAD_SYMLINK 0xE830FE76
|
||||||
|
|
||||||
|
/** Too many chained symbolic links (FAILURE, HIGH, -395) */
|
||||||
|
#define ISO_DEEP_SYMLINK 0xE830FE75
|
||||||
|
|
||||||
|
/** Unrecognized file type in ISO image (FAILURE, HIGH, -396) */
|
||||||
|
#define ISO_BAD_ISO_FILETYPE 0xE830FE74
|
||||||
|
|
||||||
|
|
||||||
/* Internal developer note:
|
/* Internal developer note:
|
||||||
Place new error codes directly above this comment.
|
Place new error codes directly above this comment.
|
||||||
Newly introduced errors must get a message entry in
|
Newly introduced errors must get a message entry in
|
||||||
libisofs/message.c, function iso_error_to_msg()
|
libisofs/messages.c, function iso_error_to_msg()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */
|
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */
|
||||||
@ -7057,42 +7593,12 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
This allows to use arbitrary program code as provider of track input data.
|
This allows to use arbitrary program code as provider of track input data.
|
||||||
|
|
||||||
Objects compliant to this interface are either provided by the application
|
Objects compliant to this interface are either provided by the application
|
||||||
or by API calls of libburn: burn_fd_source_new() , burn_file_source_new(),
|
or by API calls of libburn: burn_fd_source_new(), burn_file_source_new(),
|
||||||
and burn_fifo_source_new().
|
and burn_fifo_source_new().
|
||||||
|
|
||||||
The API calls allow to use any file object as data source. Consider to feed
|
libisofs acts as "application" and implements an own class of burn_source.
|
||||||
an eventual custom data stream asynchronously into a pipe(2) and to let
|
Instances of that class are handed out by iso_image_create_burn_source().
|
||||||
libburn handle the rest.
|
|
||||||
In this case the following rule applies:
|
|
||||||
Call burn_source_free() exactly once for every source obtained from
|
|
||||||
libburn API. You MUST NOT otherwise use or manipulate its components.
|
|
||||||
|
|
||||||
In general, burn_source objects can be freed as soon as they are attached
|
|
||||||
to track objects. The track objects will keep them alive and dispose them
|
|
||||||
when they are no longer needed. With a fifo burn_source it makes sense to
|
|
||||||
keep the own reference for inquiring its state while burning is in
|
|
||||||
progress.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
The following description of burn_source applies only to application
|
|
||||||
implemented burn_source objects. You need not to know it for API provided
|
|
||||||
ones.
|
|
||||||
|
|
||||||
If you really implement an own passive data producer by this interface,
|
|
||||||
then beware: it can do anything and it can spoil everything.
|
|
||||||
|
|
||||||
In this case the functions (*read), (*get_size), (*set_size), (*free_data)
|
|
||||||
MUST be implemented by the application and attached to the object at
|
|
||||||
creation time.
|
|
||||||
Function (*read_sub) is allowed to be NULL or it MUST be implemented and
|
|
||||||
attached.
|
|
||||||
|
|
||||||
burn_source.refcount MUST be handled properly: If not exactly as many
|
|
||||||
references are freed as have been obtained, then either memory leaks or
|
|
||||||
corrupted memory are the consequence.
|
|
||||||
All objects which are referred to by *data must be kept existent until
|
|
||||||
(*free_data) is called via burn_source_free() by the last referer.
|
|
||||||
*/
|
*/
|
||||||
struct burn_source {
|
struct burn_source {
|
||||||
|
|
||||||
@ -7225,11 +7731,6 @@ struct burn_source {
|
|||||||
/* currently none being tested */
|
/* currently none being tested */
|
||||||
|
|
||||||
|
|
||||||
/* Perform the operations promised by iso_write_opts_set_rr_reloc() */
|
|
||||||
#define Libisofs_with_rr_reloc_diR yes
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------- Experiments ---------------------------- */
|
/* ---------------------------- Experiments ---------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,9 +65,12 @@ iso_file_source_unref;
|
|||||||
iso_filesystem_ref;
|
iso_filesystem_ref;
|
||||||
iso_filesystem_unref;
|
iso_filesystem_unref;
|
||||||
iso_finish;
|
iso_finish;
|
||||||
|
iso_fs_global_id;
|
||||||
iso_get_local_charset;
|
iso_get_local_charset;
|
||||||
iso_get_messenger;
|
iso_get_messenger;
|
||||||
iso_gzip_get_refcounts;
|
iso_gzip_get_refcounts;
|
||||||
|
iso_hfsplus_xinfo_func;
|
||||||
|
iso_hfsplus_xinfo_new;
|
||||||
iso_image_add_boot_image;
|
iso_image_add_boot_image;
|
||||||
iso_image_add_mips_boot_file;
|
iso_image_add_mips_boot_file;
|
||||||
iso_image_attach_data;
|
iso_image_attach_data;
|
||||||
@ -85,6 +88,7 @@ iso_image_fs_get_volume_id;
|
|||||||
iso_image_generator_is_running;
|
iso_image_generator_is_running;
|
||||||
iso_image_get_abstract_file_id;
|
iso_image_get_abstract_file_id;
|
||||||
iso_image_get_all_boot_imgs;
|
iso_image_get_all_boot_imgs;
|
||||||
|
iso_image_get_app_use;
|
||||||
iso_image_get_application_id;
|
iso_image_get_application_id;
|
||||||
iso_image_get_attached_data;
|
iso_image_get_attached_data;
|
||||||
iso_image_get_biblio_file_id;
|
iso_image_get_biblio_file_id;
|
||||||
@ -95,18 +99,23 @@ iso_image_get_data_preparer_id;
|
|||||||
iso_image_get_mips_boot_files;
|
iso_image_get_mips_boot_files;
|
||||||
iso_image_get_msg_id;
|
iso_image_get_msg_id;
|
||||||
iso_image_get_publisher_id;
|
iso_image_get_publisher_id;
|
||||||
|
iso_image_get_pvd_times;
|
||||||
iso_image_get_root;
|
iso_image_get_root;
|
||||||
iso_image_get_session_md5;
|
iso_image_get_session_md5;
|
||||||
|
iso_image_get_sparc_core;
|
||||||
iso_image_get_system_area;
|
iso_image_get_system_area;
|
||||||
iso_image_get_system_id;
|
iso_image_get_system_id;
|
||||||
iso_image_get_volset_id;
|
iso_image_get_volset_id;
|
||||||
iso_image_get_volume_id;
|
iso_image_get_volume_id;
|
||||||
iso_image_give_up_mips_boot;
|
iso_image_give_up_mips_boot;
|
||||||
|
iso_image_hfsplus_bless;
|
||||||
|
iso_image_hfsplus_get_blessed;
|
||||||
iso_image_import;
|
iso_image_import;
|
||||||
iso_image_new;
|
iso_image_new;
|
||||||
iso_image_ref;
|
iso_image_ref;
|
||||||
iso_image_remove_boot_image;
|
iso_image_remove_boot_image;
|
||||||
iso_image_set_abstract_file_id;
|
iso_image_set_abstract_file_id;
|
||||||
|
iso_image_set_app_use;
|
||||||
iso_image_set_application_id;
|
iso_image_set_application_id;
|
||||||
iso_image_set_biblio_file_id;
|
iso_image_set_biblio_file_id;
|
||||||
iso_image_set_boot_catalog_hidden;
|
iso_image_set_boot_catalog_hidden;
|
||||||
@ -116,6 +125,7 @@ iso_image_set_copyright_file_id;
|
|||||||
iso_image_set_data_preparer_id;
|
iso_image_set_data_preparer_id;
|
||||||
iso_image_set_ignore_aclea;
|
iso_image_set_ignore_aclea;
|
||||||
iso_image_set_publisher_id;
|
iso_image_set_publisher_id;
|
||||||
|
iso_image_set_sparc_core;
|
||||||
iso_image_set_system_id;
|
iso_image_set_system_id;
|
||||||
iso_image_set_volset_id;
|
iso_image_set_volset_id;
|
||||||
iso_image_set_volume_id;
|
iso_image_set_volume_id;
|
||||||
@ -252,6 +262,7 @@ iso_tree_get_node_path;
|
|||||||
iso_tree_get_replace_mode;
|
iso_tree_get_replace_mode;
|
||||||
iso_tree_path_to_node;
|
iso_tree_path_to_node;
|
||||||
iso_tree_remove_exclude;
|
iso_tree_remove_exclude;
|
||||||
|
iso_tree_resolve_symlink;
|
||||||
iso_tree_set_follow_symlinks;
|
iso_tree_set_follow_symlinks;
|
||||||
iso_tree_set_ignore_hidden;
|
iso_tree_set_ignore_hidden;
|
||||||
iso_tree_set_ignore_special;
|
iso_tree_set_ignore_special;
|
||||||
@ -280,8 +291,13 @@ iso_write_opts_set_default_timestamp;
|
|||||||
iso_write_opts_set_default_uid;
|
iso_write_opts_set_default_uid;
|
||||||
iso_write_opts_set_dir_rec_mtime;
|
iso_write_opts_set_dir_rec_mtime;
|
||||||
iso_write_opts_set_disc_label;
|
iso_write_opts_set_disc_label;
|
||||||
|
iso_write_opts_set_efi_bootp;
|
||||||
|
iso_write_opts_set_fat;
|
||||||
iso_write_opts_set_fifo_size;
|
iso_write_opts_set_fifo_size;
|
||||||
iso_write_opts_set_hardlinks;
|
iso_write_opts_set_hardlinks;
|
||||||
|
iso_write_opts_set_hfsp_block_size;
|
||||||
|
iso_write_opts_set_hfsp_serial_number;
|
||||||
|
iso_write_opts_set_hfsplus;
|
||||||
iso_write_opts_set_iso1999;
|
iso_write_opts_set_iso1999;
|
||||||
iso_write_opts_set_iso_level;
|
iso_write_opts_set_iso_level;
|
||||||
iso_write_opts_set_joliet;
|
iso_write_opts_set_joliet;
|
||||||
@ -296,6 +312,7 @@ iso_write_opts_set_output_charset;
|
|||||||
iso_write_opts_set_overwrite_buf;
|
iso_write_opts_set_overwrite_buf;
|
||||||
iso_write_opts_set_part_offset;
|
iso_write_opts_set_part_offset;
|
||||||
iso_write_opts_set_partition_img;
|
iso_write_opts_set_partition_img;
|
||||||
|
iso_write_opts_set_prep_img;
|
||||||
iso_write_opts_set_pvd_times;
|
iso_write_opts_set_pvd_times;
|
||||||
iso_write_opts_set_record_md5;
|
iso_write_opts_set_record_md5;
|
||||||
iso_write_opts_set_relaxed_vol_atts;
|
iso_write_opts_set_relaxed_vol_atts;
|
||||||
|
@ -23,6 +23,11 @@
|
|||||||
/* for gettimeofday() */
|
/* for gettimeofday() */
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "filesrc.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
#include "eltorito.h"
|
||||||
|
#include "system_area.h"
|
||||||
|
|
||||||
|
|
||||||
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
||||||
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
under GPL which is Copyright 2002-2008 H. Peter Anvin.
|
||||||
@ -45,7 +50,7 @@ license from above stem licenses, typically from LGPL.
|
|||||||
In case its generosity is needed, here is the 2-clause BSD license:
|
In case its generosity is needed, here is the 2-clause BSD license:
|
||||||
|
|
||||||
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
||||||
and 2008-2010 Thomas Schmitt
|
and 2008-2012 Thomas Schmitt
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
@ -353,6 +358,12 @@ Main:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* The new stuff about GPT and APM which was learned from Matthew Garret
|
||||||
|
and isohybrid.c is described in doc/boot_sectord.txt chapter
|
||||||
|
"SYSLINUX isohybrid for MBR, UEFI and x86-Mac"
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
||||||
{
|
{
|
||||||
@ -377,23 +388,205 @@ 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
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
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] = {
|
||||||
|
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
|
||||||
|
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
|
||||||
|
};
|
||||||
|
static uint8_t hfs_uuid[16] = {
|
||||||
|
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
|
||||||
|
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
|
||||||
|
};
|
||||||
|
uint8_t *uuid;
|
||||||
|
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
|
||||||
|
|
||||||
|
*gpt_count = 0;
|
||||||
|
*apm_count = 0;
|
||||||
|
|
||||||
|
if (t->catalog != NULL)
|
||||||
|
num_img = t->catalog->num_bootimages;
|
||||||
|
else
|
||||||
|
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 (*gpt_count < 128)
|
||||||
|
gpt_idx[*gpt_count]= i;
|
||||||
|
(*gpt_count)++;
|
||||||
|
if ((flag & 1) && t->bootsrc[i] != NULL) {
|
||||||
|
/* Register GPT entry */
|
||||||
|
memset(gpt_name, 0, 72);
|
||||||
|
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
|
||||||
|
iso_ascii_utf_16le(gpt_name);
|
||||||
|
if (((ilx_opts >> 2) & 63) == 2)
|
||||||
|
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;
|
||||||
|
ret = iso_quick_gpt_entry(
|
||||||
|
t, t->bootsrc[i]->sections[0].block,
|
||||||
|
block_count, uuid, zero_uuid, gpt_flags,
|
||||||
|
(uint8_t *) gpt_name);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ilx_opts & 256) {
|
||||||
|
(*apm_count)++;
|
||||||
|
if ((flag & 1) && t->bootsrc[i] != NULL) {
|
||||||
|
/* Register APM entry */
|
||||||
|
block_count = 0;
|
||||||
|
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||||
|
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||||
|
ret = iso_quick_apm_entry(t, t->bootsrc[i]->sections[0].block,
|
||||||
|
block_count, "EFI", "Apple_HFS");
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
/* Prevent gap filling */
|
||||||
|
t->apm_req_flags |= 2;
|
||||||
|
t->apm_block_size = 2048;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((flag & 1) && *gpt_count > 0) {
|
||||||
|
/* Register overall GPT partition */
|
||||||
|
memset(gpt_name, 0, 72);
|
||||||
|
sprintf((char *) gpt_name, "ISOHybrid");
|
||||||
|
iso_ascii_utf_16le(gpt_name);
|
||||||
|
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
|
||||||
|
block_count = 0xffffffff;
|
||||||
|
ret = iso_quick_gpt_entry(t, (uint32_t) 0, block_count,
|
||||||
|
basic_data_uuid, zero_uuid, gpt_flags,
|
||||||
|
(uint8_t *) gpt_name);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
/* Remove ban on GPT overlapping */
|
||||||
|
t->gpt_req_flags |= 1;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Insert APM head into MBR */
|
||||||
|
static int insert_apm_head(uint8_t *buf, int apm_count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static uint8_t apm_mbr_start[32] = {
|
||||||
|
0x33, 0xed, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||||
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||||
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
|
||||||
|
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||||
|
};
|
||||||
|
static uint8_t apm_head[32] = {
|
||||||
|
0x45, 0x52, 0x08, 0x00, 0x00, 0x00, 0x90, 0x90,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
if (apm_count) {
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if(buf[i] != apm_mbr_start[i])
|
||||||
|
break;
|
||||||
|
if (i < 32) {
|
||||||
|
/* Maybe it is already patched by apm_head ? */
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if(buf[i] != apm_head[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < 32) {
|
||||||
|
iso_msgs_submit(0,
|
||||||
|
"MBR template file seems not prepared for Apple Partition Map.",
|
||||||
|
0, "FAILURE", 0);
|
||||||
|
return ISO_ISOLINUX_CANT_PATCH;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
buf[i] = apm_head[i];
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Describe GPT boot images as MBR partitions */
|
||||||
|
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
||||||
|
int gpt_idx[128], int *gpt_cursor)
|
||||||
|
{
|
||||||
|
int ilx_opts;
|
||||||
|
off_t hd_blocks;
|
||||||
|
static uint8_t dummy_chs[3] = {
|
||||||
|
0xfe, 0xff, 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
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/" */
|
||||||
|
|
||||||
|
memcpy(wpt + 5, dummy_chs, 3);
|
||||||
|
|
||||||
|
/* Start LBA (in 512 blocks) */
|
||||||
|
wpt += 8;
|
||||||
|
lsb_to_buf(&wpt, t->bootsrc[gpt_idx[*gpt_cursor]]->sections[0].block * 4,
|
||||||
|
32, 0);
|
||||||
|
|
||||||
|
/* Number of blocks */
|
||||||
|
hd_blocks = t->bootsrc[gpt_idx[*gpt_cursor]]->sections[0].size;
|
||||||
|
hd_blocks = hd_blocks / 512 + !!(hd_blocks % 512);
|
||||||
|
lsb_to_buf(&wpt, (int) hd_blocks, 32, 0);
|
||||||
|
|
||||||
|
(*gpt_cursor)++;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag bit0= make own random MBR Id from current time
|
* @param flag bit0= make own random MBR Id from current time
|
||||||
*/
|
*/
|
||||||
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||||
uint32_t mbr_id, int head_count, int sector_count,
|
|
||||||
int part_offset, int part_number, int fs_type,
|
int part_offset, int part_number, int fs_type,
|
||||||
uint8_t *buf, int flag)
|
uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
uint32_t id, part, nominal_part_size;
|
uint32_t id, part, nominal_part_size;
|
||||||
off_t hd_img_blocks, hd_boot_lba;
|
off_t hd_img_blocks, hd_boot_lba;
|
||||||
char *wpt;
|
char *wpt;
|
||||||
|
uint32_t boot_lba;
|
||||||
|
int head_count, sector_count, ret;
|
||||||
|
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
|
||||||
/* For generating a weak random number */
|
/* For generating a weak random number */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
|
|
||||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||||
|
|
||||||
|
boot_lba = t->bootsrc[0]->sections[0].block;
|
||||||
|
head_count = t->partition_heads_per_cyl;
|
||||||
|
sector_count = t->partition_secs_per_head;
|
||||||
|
|
||||||
|
ret = assess_isohybrid_gpt_apm(t, &gpt_count, gpt_idx, &apm_count, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* The rest of APM has already been written by iso_write_apm().
|
||||||
|
But the isohybrid APM head differs from the hfsplus_writer APM head.
|
||||||
|
*/
|
||||||
|
ret = insert_apm_head(buf, apm_count);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Padding of image_size to a multiple of sector_count*head_count
|
/* Padding of image_size to a multiple of sector_count*head_count
|
||||||
happens already at compute time and is implemented by
|
happens already at compute time and is implemented by
|
||||||
an appropriate increase of Ecma119Image->tail_blocks.
|
an appropriate increase of Ecma119Image->tail_blocks.
|
||||||
@ -414,6 +607,8 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
gettimeofday(&tv, &tz);
|
gettimeofday(&tv, &tz);
|
||||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||||
lsb_to_buf(&wpt, id, 32, 0);
|
lsb_to_buf(&wpt, id, 32, 0);
|
||||||
|
} else {
|
||||||
|
wpt+= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write word 0 # Offset 444
|
/* write word 0 # Offset 444
|
||||||
@ -422,10 +617,21 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
|
|
||||||
/* # Offset 446
|
/* # Offset 446
|
||||||
*/
|
*/
|
||||||
|
gpt_cursor= 0;
|
||||||
for (part = 1 ; part <= 4; part++) {
|
for (part = 1 ; part <= 4; part++) {
|
||||||
if ((int) part != part_number) {
|
if ((int) part != part_number) {
|
||||||
/* if this_partition != partition_number: write 16 zero bytes */
|
/* if this_partition != partition_number: write 16 zero bytes
|
||||||
|
(this is now overriden by the eventual desire to announce
|
||||||
|
EFI and HFS boot images.)
|
||||||
|
*/
|
||||||
memset(wpt, 0, 16);
|
memset(wpt, 0, 16);
|
||||||
|
|
||||||
|
if (gpt_cursor < gpt_count) {
|
||||||
|
ret = gpt_images_as_mbr_partitions(t, wpt, gpt_idx,
|
||||||
|
&gpt_cursor);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
wpt+= 16;
|
wpt+= 16;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Thomas Schmitt
|
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -527,19 +527,25 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
if (md5_pt == NULL)
|
if (md5_pt == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
if (!target->will_cancel) {
|
||||||
&value, 0);
|
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
||||||
if (ret == 1 && value_length == 4) {
|
&value, 0);
|
||||||
for (i = 0; i < 4; i++)
|
if (ret == 1 && value_length == 4) {
|
||||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
for (i = 0; i < 4; i++)
|
||||||
if (idx > 0 && idx <= target->checksum_idx_counter) {
|
idx = (idx << 8) | ((unsigned char *) value)[i];
|
||||||
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
|
if (idx > 0 && idx <= target->checksum_idx_counter) {
|
||||||
|
memcpy(target->checksum_buffer + 16 * idx, md5_pt, 16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (value != NULL)
|
||||||
|
free(value);
|
||||||
|
|
||||||
|
/* >>> ts B30114 : It is unclear why these are removed here.
|
||||||
|
At least with the opts->will_cancel runs,
|
||||||
|
this is not appropriate.
|
||||||
|
*/
|
||||||
|
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
||||||
}
|
}
|
||||||
if (value != NULL)
|
|
||||||
free(value);
|
|
||||||
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
|
||||||
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
|
|
||||||
}
|
}
|
||||||
} else if (node->type == LIBISO_DIR) {
|
} else if (node->type == LIBISO_DIR) {
|
||||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||||
|
@ -139,6 +139,7 @@ int iso_node_xinfo_dispose_cloners(int flag)
|
|||||||
next = assoc->next;
|
next = assoc->next;
|
||||||
free((char *) assoc);
|
free((char *) assoc);
|
||||||
}
|
}
|
||||||
|
iso_xinfo_cloner_list= NULL;
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +216,10 @@ LIBJTE_MISCONFIGURATION_ = 0;
|
|||||||
iso_px_ino_xinfo_cloner, 0);
|
iso_px_ino_xinfo_cloner, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
ret = iso_node_xinfo_make_clonable(iso_hfsplus_xinfo_func,
|
||||||
|
iso_hfsplus_xinfo_cloner, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,9 +345,9 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
case ISO_WRONG_PVD:
|
case ISO_WRONG_PVD:
|
||||||
return "Wrong or damaged Primary Volume Descriptor";
|
return "Wrong or damaged Primary Volume Descriptor";
|
||||||
case ISO_WRONG_RR:
|
case ISO_WRONG_RR:
|
||||||
return "Wrong or damaged RR entry";
|
return "Wrong or damaged Rock Ridge entry";
|
||||||
case ISO_UNSUPPORTED_RR:
|
case ISO_UNSUPPORTED_RR:
|
||||||
return "Unsupported RR feature";
|
return "Unsupported Rock Ridge feature";
|
||||||
case ISO_WRONG_ECMA119:
|
case ISO_WRONG_ECMA119:
|
||||||
return "Wrong or damaged ECMA-119";
|
return "Wrong or damaged ECMA-119";
|
||||||
case ISO_UNSUPPORTED_ECMA119:
|
case ISO_UNSUPPORTED_ECMA119:
|
||||||
@ -356,9 +361,9 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
case ISO_UNSUPPORTED_SUSP:
|
case ISO_UNSUPPORTED_SUSP:
|
||||||
return "Unsupported SUSP feature";
|
return "Unsupported SUSP feature";
|
||||||
case ISO_WRONG_RR_WARN:
|
case ISO_WRONG_RR_WARN:
|
||||||
return "Error on a RR entry that can be ignored";
|
return "Error on a Rock Ridge entry that can be ignored";
|
||||||
case ISO_SUSP_UNHANDLED:
|
case ISO_SUSP_UNHANDLED:
|
||||||
return "Error on a RR entry that can be ignored";
|
return "Unhandled SUSP entry";
|
||||||
case ISO_SUSP_MULTIPLE_ER:
|
case ISO_SUSP_MULTIPLE_ER:
|
||||||
return "Multiple ER SUSP entries found";
|
return "Multiple ER SUSP entries found";
|
||||||
case ISO_UNSUPPORTED_VD:
|
case ISO_UNSUPPORTED_VD:
|
||||||
@ -447,7 +452,7 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
case ISO_BAD_PARTITION_FILE:
|
case ISO_BAD_PARTITION_FILE:
|
||||||
return "Cannot open data file for appended partition";
|
return "Cannot open data file for appended partition";
|
||||||
case ISO_NON_MBR_SYS_AREA:
|
case ISO_NON_MBR_SYS_AREA:
|
||||||
return "May not combine appended partition with non-MBR system area";
|
return "May not combine MBR partition with non-MBR system area";
|
||||||
case ISO_DISPLACE_ROLLOVER:
|
case ISO_DISPLACE_ROLLOVER:
|
||||||
return "Displacement offset leads outside 32 bit range";
|
return "Displacement offset leads outside 32 bit range";
|
||||||
case ISO_NAME_NEEDS_TRANSL:
|
case ISO_NAME_NEEDS_TRANSL:
|
||||||
@ -468,6 +473,36 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Attribute name cannot be represented";
|
return "Attribute name cannot be represented";
|
||||||
case ISO_AAIP_ACL_MULT_OBJ:
|
case ISO_AAIP_ACL_MULT_OBJ:
|
||||||
return "ACL text contains multiple entries of user::, group::, other::";
|
return "ACL text contains multiple entries of user::, group::, other::";
|
||||||
|
case ISO_SECT_SCATTERED:
|
||||||
|
return "File sections do not form consecutive array of blocks";
|
||||||
|
case ISO_BOOT_TOO_MANY_APM:
|
||||||
|
return "Too many Apple Partition Map entries requested";
|
||||||
|
case ISO_BOOT_APM_OVERLAP:
|
||||||
|
return "Overlapping Apple Partition Map entries requested";
|
||||||
|
case ISO_BOOT_TOO_MANY_GPT:
|
||||||
|
return "Too many GPT entries requested";
|
||||||
|
case ISO_BOOT_GPT_OVERLAP:
|
||||||
|
return "Overlapping GPT entries requested";
|
||||||
|
case ISO_BOOT_TOO_MANY_MBR:
|
||||||
|
return "Too many MBR partition entries requested";
|
||||||
|
case ISO_BOOT_MBR_OVERLAP:
|
||||||
|
return "Overlapping MBR partition entries requested";
|
||||||
|
case ISO_BOOT_MBR_COLLISION:
|
||||||
|
return "Attempt to use an MBR partition entry twice";
|
||||||
|
case ISO_BOOT_NO_EFI_ELTO:
|
||||||
|
return "No suitable El Torito EFI boot image for exposure as GPT partition";
|
||||||
|
case ISO_BOOT_HFSP_BAD_BSIZE:
|
||||||
|
return "Not a supported HFS+ or APM block size";
|
||||||
|
case ISO_BOOT_APM_GPT_BSIZE:
|
||||||
|
return "APM block size prevents coexistence with GPT";
|
||||||
|
case ISO_HFSP_NO_MANGLE:
|
||||||
|
return "Name collision in HFS+, mangling not possible";
|
||||||
|
case ISO_DEAD_SYMLINK:
|
||||||
|
return "Symbolic link cannot be resolved";
|
||||||
|
case ISO_DEEP_SYMLINK:
|
||||||
|
return "Too many chained symbolic links";
|
||||||
|
case ISO_BAD_ISO_FILETYPE:
|
||||||
|
return "Unrecognized file type in ISO image";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,8 @@ void iso_node_ref(IsoNode *node)
|
|||||||
*/
|
*/
|
||||||
void iso_node_unref(IsoNode *node)
|
void iso_node_unref(IsoNode *node)
|
||||||
{
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
return;
|
||||||
if (--node->refcount == 0) {
|
if (--node->refcount == 0) {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case LIBISO_DIR:
|
case LIBISO_DIR:
|
||||||
@ -1046,6 +1048,7 @@ void iso_node_set_sort_weight(IsoNode *node, int w)
|
|||||||
}
|
}
|
||||||
} else if (node->type == LIBISO_FILE) {
|
} else if (node->type == LIBISO_FILE) {
|
||||||
((IsoFile*)node)->sort_weight = w;
|
((IsoFile*)node)->sort_weight = w;
|
||||||
|
((IsoFile*)node)->explicit_weight = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1428,6 +1431,8 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
|||||||
new->node.type = LIBISO_FILE;
|
new->node.type = LIBISO_FILE;
|
||||||
new->node.name = name;
|
new->node.name = name;
|
||||||
new->node.mode = S_IFREG;
|
new->node.mode = S_IFREG;
|
||||||
|
new->from_old_session = 0;
|
||||||
|
new->explicit_weight = 0;
|
||||||
new->sort_weight = 0;
|
new->sort_weight = 0;
|
||||||
new->stream = stream;
|
new->stream = stream;
|
||||||
|
|
||||||
@ -1725,6 +1730,7 @@ int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
|
|||||||
bit2= delete the given names rather than overwrite
|
bit2= delete the given names rather than overwrite
|
||||||
their content
|
their content
|
||||||
bit4= do not overwrite value of empty name
|
bit4= do not overwrite value of empty name
|
||||||
|
bit5= do not overwrite isofs attributes
|
||||||
bit15= release memory and return 1
|
bit15= release memory and return 1
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
@ -1773,6 +1779,8 @@ int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
|
|||||||
continue;
|
continue;
|
||||||
if (names[i][0] == 0 && (flag & 16))
|
if (names[i][0] == 0 && (flag & 16))
|
||||||
continue;
|
continue;
|
||||||
|
if ((flag & 32) && strncmp(names[i], "isofs.", 6) == 0)
|
||||||
|
continue;
|
||||||
for (j = 0; j < *m_num_attrs; j++) {
|
for (j = 0; j < *m_num_attrs; j++) {
|
||||||
if ((*m_names)[j] == NULL)
|
if ((*m_names)[j] == NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -1818,6 +1826,8 @@ int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
|
|||||||
continue;
|
continue;
|
||||||
if (names[i][0] == 0 && (flag & 16))
|
if (names[i][0] == 0 && (flag & 16))
|
||||||
continue;
|
continue;
|
||||||
|
if ((flag & 32) && strncmp(names[i], "isofs.", 6) == 0)
|
||||||
|
continue;
|
||||||
for (j = 0; j < *m_num_attrs; j++) {
|
for (j = 0; j < *m_num_attrs; j++) {
|
||||||
if ((*m_names)[j] == NULL)
|
if ((*m_names)[j] == NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -1868,13 +1878,13 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
|||||||
for (i = 0; i < num_attrs; i++)
|
for (i = 0; i < num_attrs; i++)
|
||||||
if (strncmp(names[i], "user.", 5) != 0 && names[i][0] != 0)
|
if (strncmp(names[i], "user.", 5) != 0 && names[i][0] != 0)
|
||||||
return ISO_AAIP_NON_USER_NAME;
|
return ISO_AAIP_NON_USER_NAME;
|
||||||
|
if ((flag & (2 | 4 | 16)) || !(flag & 8)) {
|
||||||
if ((flag & (2 | 4)) || !(flag & 8)) {
|
|
||||||
/* Merge old and new lists */
|
/* Merge old and new lists */
|
||||||
ret = iso_node_merge_xattr(
|
ret = iso_node_merge_xattr(
|
||||||
node, num_attrs, names, value_lengths, values,
|
node, num_attrs, names, value_lengths, values,
|
||||||
&m_num, &m_names, &m_value_lengths, &m_values,
|
&m_num, &m_names, &m_value_lengths, &m_values,
|
||||||
(flag & 4) | (!(flag & 2)) | ((!(flag & 1)) << 4));
|
(flag & 4) | (!(flag & 2)) | ((!(flag & 1)) << 4) |
|
||||||
|
((flag & 16) << 1));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
num_attrs = m_num;
|
num_attrs = m_num;
|
||||||
@ -2559,6 +2569,7 @@ int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
|||||||
ret = iso_stream_set_image_ino(file->stream, ino, 0);
|
ret = iso_stream_set_image_ino(file->stream, ino, 0);
|
||||||
if (ret < 0 || ret == 1)
|
if (ret < 0 || ret == 1)
|
||||||
return ret;
|
return ret;
|
||||||
|
/* ret == 0 means that the stream is not from loaded ISO image */
|
||||||
|
|
||||||
} else if (node->type == LIBISO_SYMLINK) {
|
} else if (node->type == LIBISO_SYMLINK) {
|
||||||
symlink = (IsoSymlink *) node;
|
symlink = (IsoSymlink *) node;
|
||||||
@ -2749,6 +2760,8 @@ int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= delete isofs.cx rather than setting it
|
||||||
|
*/
|
||||||
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
@ -2758,9 +2771,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
|||||||
char *valuept;
|
char *valuept;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
|
valuept= (char *) value;
|
||||||
|
if (flag & 1) {
|
||||||
|
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||||
|
&names, value_lengths, &valuept, 4 | 8);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
||||||
valuept= (char *) value;
|
|
||||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||||
&names, value_lengths, &valuept, 2 | 8);
|
&names, value_lengths, &valuept, 2 | 8);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -149,8 +149,15 @@ struct Iso_File
|
|||||||
{
|
{
|
||||||
IsoNode node;
|
IsoNode node;
|
||||||
|
|
||||||
|
/* 1 = The node was loaded from an existing ISO image and still refers
|
||||||
|
to its data content there.
|
||||||
|
*/
|
||||||
unsigned int from_old_session : 1;
|
unsigned int from_old_session : 1;
|
||||||
|
|
||||||
|
/* 1 = The node got attributed a weight by iso_node_set_sort_weight().
|
||||||
|
*/
|
||||||
|
unsigned int explicit_weight : 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It sorts the order in which the file data is written to the CD image.
|
* It sorts the order in which the file data is written to the CD image.
|
||||||
* Higher weighting files are written at the beginning of image
|
* Higher weighting files are written at the beginning of image
|
||||||
|
@ -1246,17 +1246,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
|||||||
/* we need to add a RE entry */
|
/* we need to add a RE entry */
|
||||||
su_size += 4;
|
su_size += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
||||||
(t->rr_reloc_flags & 1)) {
|
(t->rr_reloc_flags & 1)) {
|
||||||
/* The dedicated relocation directory shall be marked by RE */
|
/* The dedicated relocation directory shall be marked by RE */
|
||||||
su_size += 4;
|
su_size += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
} else if (n->type == ECMA119_SPECIAL) {
|
} else if (n->type == ECMA119_SPECIAL) {
|
||||||
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
||||||
/* block or char device, we need a PN entry */
|
/* block or char device, we need a PN entry */
|
||||||
@ -1442,18 +1436,12 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Libisofs_with_rr_reloc_diR
|
|
||||||
|
|
||||||
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
||||||
(t->rr_reloc_flags & 1)) {
|
(t->rr_reloc_flags & 1)) {
|
||||||
/* The dedicated relocation directory shall be marked by RE */
|
/* The dedicated relocation directory shall be marked by RE */
|
||||||
ret = rrip_add_RE(t, node, info);
|
ret = rrip_add_RE(t, node, info);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
#endif /* Libisofs_with_rr_reloc_diR */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (n->type == ECMA119_SPECIAL) {
|
} else if (n->type == ECMA119_SPECIAL) {
|
||||||
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
||||||
|
@ -890,17 +890,27 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @param flag bit0= Obtain most fundamental stream */
|
||||||
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag)
|
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag)
|
||||||
{
|
{
|
||||||
IsoStreamIface* class;
|
IsoStreamIface* class;
|
||||||
|
IsoStream *result = NULL, *next;
|
||||||
|
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
class = stream->class;
|
while (1) {
|
||||||
if (class->version < 2)
|
class = stream->class;
|
||||||
return NULL;
|
if (class->version < 2)
|
||||||
return class->get_input_stream(stream, 0);
|
return result;
|
||||||
|
next = class->get_input_stream(stream, 0);
|
||||||
|
if (next == NULL)
|
||||||
|
return result;
|
||||||
|
result = next;
|
||||||
|
if (!(flag & 1))
|
||||||
|
return result;
|
||||||
|
stream = result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *iso_stream_get_source_path(IsoStream *stream, int flag)
|
char *iso_stream_get_source_path(IsoStream *stream, int flag)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Vreixo Formoso
|
* Copyright (c) 2008 Vreixo Formoso
|
||||||
|
* Copyright (c) 2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -63,4 +64,219 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag);
|
|||||||
*/
|
*/
|
||||||
int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* The parameter struct for production of a single MBR partition entry.
|
||||||
|
See also the description of MBR in doc/boot_sectors.txt.
|
||||||
|
No sorting by start sector and gap filling is done before the System Area
|
||||||
|
gets written. But the entries may get assigned to a desired slot number
|
||||||
|
in the table.
|
||||||
|
Requested entries with block_count == 0 get expanded to the start of
|
||||||
|
the next requested entry resp. to image end, if no entry follows.
|
||||||
|
start_block of a follwing entry must be at least a high as the sum of
|
||||||
|
start_block and block_count of the previous entry.
|
||||||
|
Empty requested entries will be represented as 16 bytes of 0.
|
||||||
|
*/
|
||||||
|
struct iso_mbr_partition_request {
|
||||||
|
|
||||||
|
/* Always given in blocks of 512 bytes */
|
||||||
|
uint64_t start_block;
|
||||||
|
|
||||||
|
/* A block count of 0 means that the partition reaches up to the start of
|
||||||
|
the next one.
|
||||||
|
*/
|
||||||
|
uint64_t block_count;
|
||||||
|
|
||||||
|
/* Partition type */
|
||||||
|
uint8_t type_byte;
|
||||||
|
|
||||||
|
/* 0x80 = bootable */
|
||||||
|
uint8_t status_byte;
|
||||||
|
|
||||||
|
/* If >= 1 && <= 4 : The partition slot number in MBR.
|
||||||
|
If more than one partition desires the same slot, then an error
|
||||||
|
ISO_BOOT_MBR_COLLISION occurs at registration time.
|
||||||
|
Use iso_mbr_entry_slot_is_free() to detect this in advance.
|
||||||
|
If desired_slot is 0, then the partition entry is put into the
|
||||||
|
lowest MBR slot that is not occupied by an entry with desired_slot > 0
|
||||||
|
or by an entry that was registered before this entry.
|
||||||
|
*/
|
||||||
|
int desired_slot;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Copies the content of req and registers it in t.mbr_req[].
|
||||||
|
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||||
|
Submit 0 as value flag.
|
||||||
|
*/
|
||||||
|
int iso_register_mbr_entry(Ecma119Image *t,
|
||||||
|
struct iso_mbr_partition_request *req, int flag);
|
||||||
|
|
||||||
|
/* Convenience frontend for iso_register_mbr_entry().
|
||||||
|
name and type are 0-terminated strings, which may get silently truncated.
|
||||||
|
*/
|
||||||
|
int iso_quick_mbr_entry(Ecma119Image *t,
|
||||||
|
uint64_t start_block, uint64_t block_count,
|
||||||
|
uint8_t type_byte, uint8_t status_byte,
|
||||||
|
int desired_slot);
|
||||||
|
|
||||||
|
/* Peek in advance whether a desired slot number is already occupied by a
|
||||||
|
registered MBR entry.
|
||||||
|
Parameter slot may be between 0 and 4. 0 always returns "free".
|
||||||
|
Return value is 0 if occupied, 1 if free, and -1 if the slot number is
|
||||||
|
out of range.
|
||||||
|
*/
|
||||||
|
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot);
|
||||||
|
|
||||||
|
|
||||||
|
/* The parameter struct for production of a single Apple Partition Map entry.
|
||||||
|
See also the partial APM description in doc/boot_sectors.txt.
|
||||||
|
The list of entries is stored in Ecma119Image.apm_req.
|
||||||
|
The size of a block can be chosen by setting Ecma119Image.apm_block_size.
|
||||||
|
If an entry has start_block <=1, then its block_count will be adjusted
|
||||||
|
to the final size of the partition map.
|
||||||
|
If no such entry is requested, then it will be prepended automatically
|
||||||
|
with name "Apple" and type "Apple_partition_map".
|
||||||
|
The requested entries will get sorted and gaps will be filled by more
|
||||||
|
entries.
|
||||||
|
*/
|
||||||
|
struct iso_apm_partition_request {
|
||||||
|
|
||||||
|
/* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4).
|
||||||
|
Written to the ISO image according to Ecma119Image.apm_block_size.
|
||||||
|
*/
|
||||||
|
uint32_t start_block;
|
||||||
|
uint32_t block_count;
|
||||||
|
|
||||||
|
/* All 32 bytes get copied to the system area.
|
||||||
|
Take care to pad up short strings by 0.
|
||||||
|
*/
|
||||||
|
uint8_t name[32];
|
||||||
|
uint8_t type[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Copies the content of req and registers it in t.apm_req[].
|
||||||
|
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||||
|
Submit 0 as value flag.
|
||||||
|
*/
|
||||||
|
int iso_register_apm_entry(Ecma119Image *t,
|
||||||
|
struct iso_apm_partition_request *req, int flag);
|
||||||
|
|
||||||
|
/* Convenience frontend for iso_register_apm_entry().
|
||||||
|
name and type are 0-terminated strings, which may get silently truncated.
|
||||||
|
*/
|
||||||
|
int iso_quick_apm_entry(Ecma119Image *t,
|
||||||
|
uint32_t start_block, uint32_t block_count, char *name, char *type);
|
||||||
|
|
||||||
|
|
||||||
|
/* CRC-32 as of GPT and Ethernet.
|
||||||
|
*/
|
||||||
|
unsigned int iso_crc32_gpt(unsigned char *data, int count, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* These two pseudo-random generators produce byte strings which will
|
||||||
|
surely not duplicate in the first 256 calls. If more calls are necessary
|
||||||
|
in the same process, then one must wait until the output of
|
||||||
|
gettimeofday(2) changes.
|
||||||
|
It is advised to obtain them as late as possible, so that Ecma119Image *t
|
||||||
|
can distinguish itself from other image production setups which might be
|
||||||
|
run on other machines with the same process number at the same time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Produces a weakly random variation of a hardcoded real random uuid
|
||||||
|
*/
|
||||||
|
void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
|
||||||
|
|
||||||
|
|
||||||
|
/* The parameter struct for production of a single GPT entry.
|
||||||
|
See also the partial GPT description in doc/boot_sectors.txt.
|
||||||
|
The list of entries is stored in Ecma119Image.gpt_req.
|
||||||
|
The GPT header block at byte 0x200 will get produced automatically.
|
||||||
|
The requested entries will get sorted and gaps will be filled by more
|
||||||
|
entries. Overlapping partitions are allowed only if
|
||||||
|
(Ecma119Image.gpt_req_flags & 1).
|
||||||
|
The block_count will be truncated to the image size before the GPT backup.
|
||||||
|
|
||||||
|
The GPT entries will be stored after the Apple Partition Map, if such
|
||||||
|
gets generated too. Both partition descriptions must fit into the 32 KiB
|
||||||
|
of the ISO 9660 System Area.
|
||||||
|
GPT can be combined with APM only if (Ecma119Image.apm_block_size > 512).
|
||||||
|
Otherwise, block 1 of APM and GPT header block would collide.
|
||||||
|
So Ecma119Image.apm_block_size is set automatically to 2048 if at least
|
||||||
|
one GPT entry is requested. (One could try 1024 ...).
|
||||||
|
*/
|
||||||
|
struct iso_gpt_partition_request {
|
||||||
|
|
||||||
|
/* Always given in blocks of 2 KiB.
|
||||||
|
Written to the ISO image in blocks of 512.
|
||||||
|
*/
|
||||||
|
uint32_t start_block;
|
||||||
|
uint32_t block_count;
|
||||||
|
|
||||||
|
/* The registered GUID which defines the partition type */
|
||||||
|
uint8_t type_guid[16];
|
||||||
|
|
||||||
|
/* An individual GUID which shall be unique to the partition.
|
||||||
|
If the caller submits 0...0 then a (weak) random uuid will be generated.
|
||||||
|
*/
|
||||||
|
uint8_t partition_guid[16];
|
||||||
|
|
||||||
|
/* bit0= "System Partition" Do not alter,
|
||||||
|
bit2= Legacy BIOS bootable (MBR partition type 0x80)
|
||||||
|
bit60= read-only
|
||||||
|
*/
|
||||||
|
uint64_t flags;
|
||||||
|
|
||||||
|
/* Fill with text encoded as UTF-16LE.
|
||||||
|
All 72 bytes get copied to the system area.
|
||||||
|
Take care to pad up short strings by 0.
|
||||||
|
*/
|
||||||
|
uint8_t name[72];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Copies the content of req and registers it in t.gpt_req[].
|
||||||
|
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||||
|
Submit 0 as value flag.
|
||||||
|
*/
|
||||||
|
int iso_register_gpt_entry(Ecma119Image *t,
|
||||||
|
struct iso_gpt_partition_request *req, int flag);
|
||||||
|
|
||||||
|
/* Convenience frontend for iso_register_gpt_entry().
|
||||||
|
name has to be already encoded as UTF-16LE.
|
||||||
|
*/
|
||||||
|
int iso_quick_gpt_entry(Ecma119Image *t,
|
||||||
|
uint32_t start_block, uint32_t block_count,
|
||||||
|
uint8_t type_guid[16], uint8_t partition_guid[16],
|
||||||
|
uint64_t flags, uint8_t name[72]);
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal helper that will be used by system_area.c and make_isohybrid_mbr.c
|
||||||
|
*/
|
||||||
|
int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
|
||||||
|
uint8_t *buf, uint32_t max_entries,
|
||||||
|
uint32_t part_start, uint32_t p_arr_crc);
|
||||||
|
|
||||||
|
/* Creates the Partition Prepend writer.
|
||||||
|
*/
|
||||||
|
int partprepend_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
|
/* Creates the GPT backup tail writer.
|
||||||
|
*/
|
||||||
|
int gpt_tail_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
|
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
|
||||||
|
void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
||||||
|
|
||||||
|
|
||||||
|
/* Parameters of MBR patching for GRUB2
|
||||||
|
Might later become variables in Ecma119Image
|
||||||
|
*/
|
||||||
|
#define Libisofs_grub2_mbr_patch_poS 0x1b0
|
||||||
|
#define Libisofs_grub2_mbr_patch_offsT 4
|
||||||
|
|
||||||
|
/* Parameters of SUN Disk Label patching for GRUB2
|
||||||
|
See API iso_image_set_sparc_core().
|
||||||
|
*/
|
||||||
|
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
|
||||||
|
#define Libisofs_grub2_sparc_patch_size_poS 0x230
|
||||||
|
|
||||||
#endif /* SYSTEM_AREA_H_ */
|
#endif /* SYSTEM_AREA_H_ */
|
||||||
|
@ -803,6 +803,8 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
ret = iso_file_source_lstat(file, &info);
|
ret = iso_file_source_lstat(file, &info);
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
||||||
|
"Error when adding file %s", path);
|
||||||
goto dir_rec_continue;
|
goto dir_rec_continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,3 +1198,84 @@ int iso_tree_clone(IsoNode *node,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_tree_resolve_symlink(IsoImage *img, IsoSymlink *sym, IsoNode **res,
|
||||||
|
int *depth, int flag)
|
||||||
|
{
|
||||||
|
IsoDir *cur_dir = NULL;
|
||||||
|
IsoNode *n, *resolved_node;
|
||||||
|
char *dest, *dest_start, *dest_end;
|
||||||
|
int ret = 0;
|
||||||
|
unsigned int comp_len, dest_len;
|
||||||
|
|
||||||
|
dest = sym->dest;
|
||||||
|
dest_len = strlen(dest);
|
||||||
|
|
||||||
|
if (dest[0] == '/') {
|
||||||
|
|
||||||
|
/* ??? How to resolve absolute links without knowing the
|
||||||
|
path of the future mount point ?
|
||||||
|
??? Would it be better to throw error ?
|
||||||
|
I can only assume that it gets mounted at / during some stage
|
||||||
|
of booting.
|
||||||
|
*/;
|
||||||
|
|
||||||
|
cur_dir = img->root;
|
||||||
|
dest_end = dest;
|
||||||
|
} else {
|
||||||
|
cur_dir = sym->node.parent;
|
||||||
|
if (cur_dir == NULL)
|
||||||
|
cur_dir = img->root;
|
||||||
|
dest_end = dest - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dest_end < dest + dest_len) {
|
||||||
|
dest_start = dest_end + 1;
|
||||||
|
dest_end = strchr(dest_start, '/');
|
||||||
|
if (dest_end == NULL)
|
||||||
|
dest_end = dest_start + strlen(dest_start);
|
||||||
|
comp_len = dest_end - dest_start;
|
||||||
|
if (comp_len == 0 || (comp_len == 1 && dest_start[0] == '.'))
|
||||||
|
continue;
|
||||||
|
if (comp_len == 2 && dest_start[0] == '.' && dest_start[1] == '.') {
|
||||||
|
cur_dir = cur_dir->node.parent;
|
||||||
|
if (cur_dir == NULL) /* link shoots over root */
|
||||||
|
return ISO_DEAD_SYMLINK;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search node in cur_dir */
|
||||||
|
for (n = cur_dir->children; n != NULL; n = n->next)
|
||||||
|
if (strncmp(dest_start, n->name, comp_len) == 0 &&
|
||||||
|
strlen(n->name) == comp_len)
|
||||||
|
break;
|
||||||
|
if (n == NULL)
|
||||||
|
return ISO_DEAD_SYMLINK;
|
||||||
|
|
||||||
|
if (n->type == LIBISO_DIR) {
|
||||||
|
cur_dir = (IsoDir *) n;
|
||||||
|
} else if (n->type == LIBISO_SYMLINK) {
|
||||||
|
if (*depth >= LIBISO_MAX_LINK_DEPTH)
|
||||||
|
return ISO_DEEP_SYMLINK;
|
||||||
|
(*depth)++;
|
||||||
|
ret = iso_tree_resolve_symlink(img, (IsoSymlink *) n,
|
||||||
|
&resolved_node, depth, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (resolved_node->type != LIBISO_DIR) {
|
||||||
|
n = resolved_node;
|
||||||
|
goto leaf_type;
|
||||||
|
}
|
||||||
|
cur_dir = (IsoDir *) resolved_node;
|
||||||
|
} else {
|
||||||
|
leaf_type:;
|
||||||
|
if (dest_end < dest + dest_len) /* attempt to dive into file */
|
||||||
|
return ISO_DEAD_SYMLINK;
|
||||||
|
*res = n;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*res = (IsoNode *) cur_dir;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
153
libisofs/util.c
153
libisofs/util.c
@ -667,6 +667,123 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int str2utf16be(const char *icharset, const char *input, uint16_t **output)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
wchar_t *wsrc_ = NULL;
|
||||||
|
char *src;
|
||||||
|
char *ret = NULL;
|
||||||
|
char *ret_ = NULL;
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret = 0;
|
||||||
|
int direct_conv = 0;
|
||||||
|
size_t loop_counter = 0, loop_limit = 3;
|
||||||
|
size_t numchars;
|
||||||
|
size_t outbytes;
|
||||||
|
size_t inbytes;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (icharset == NULL || input == NULL || output == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Try the direct conversion.
|
||||||
|
*/
|
||||||
|
conv_ret = iso_iconv_open(&conv, "UTF-16BE", (char *) icharset, 0);
|
||||||
|
if (conv_ret > 0) {
|
||||||
|
direct_conv = 1;
|
||||||
|
src = (char *) input;
|
||||||
|
inbytes = strlen(input);
|
||||||
|
loop_limit = inbytes + 3;
|
||||||
|
outbytes = (2 * inbytes + 1) * sizeof(uint16_t);
|
||||||
|
ret_ = malloc(outbytes);
|
||||||
|
if (ret_ == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
ret = ret_;
|
||||||
|
} else {
|
||||||
|
/* Try via intermediate character set WCHAR_T.
|
||||||
|
*/
|
||||||
|
result = str2wchar(icharset, input, &wsrc_);
|
||||||
|
if (result == (int) ISO_SUCCESS) {
|
||||||
|
src = (char *)wsrc_;
|
||||||
|
numchars = wcslen(wsrc_);
|
||||||
|
|
||||||
|
inbytes = numchars * sizeof(wchar_t);
|
||||||
|
loop_limit = inbytes + 3;
|
||||||
|
|
||||||
|
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
|
||||||
|
if (ret_ == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
outbytes = 2 * numchars * sizeof(uint16_t);
|
||||||
|
ret = ret_;
|
||||||
|
|
||||||
|
/* initialize iconv */
|
||||||
|
conv_ret = iso_iconv_open(&conv, "UTF-16BE", "WCHAR_T", 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
free(wsrc_);
|
||||||
|
free(ret_);
|
||||||
|
}
|
||||||
|
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
while (n == (size_t) -1) {
|
||||||
|
/* The destination buffer is too small. Stops here. */
|
||||||
|
if (errno == E2BIG)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* An incomplete multi bytes sequence was found. We
|
||||||
|
* can't do anything here. That's quite unlikely. */
|
||||||
|
if (errno == EINVAL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* The last possible error is an invalid multi bytes
|
||||||
|
* sequence. Just replace the character with a "_".
|
||||||
|
* Probably the character doesn't exist in UCS */
|
||||||
|
set_ucsbe((uint16_t*) ret, '_');
|
||||||
|
ret += sizeof(uint16_t);
|
||||||
|
outbytes -= sizeof(uint16_t);
|
||||||
|
|
||||||
|
if (!outbytes)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* There was an error with one character but some other remain
|
||||||
|
* to be converted. That's probably a multibyte character.
|
||||||
|
* See above comment. */
|
||||||
|
if (direct_conv) {
|
||||||
|
src++;
|
||||||
|
inbytes--;
|
||||||
|
} else {
|
||||||
|
src += sizeof(wchar_t);
|
||||||
|
inbytes -= sizeof(wchar_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inbytes)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Just to appease my remorse about unclear loop ends */
|
||||||
|
loop_counter++;
|
||||||
|
if (loop_counter > loop_limit)
|
||||||
|
break;
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
}
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
|
||||||
|
/* close the UTF-16 string */
|
||||||
|
set_ucsbe((uint16_t*) ret, '\0');
|
||||||
|
if (wsrc_ != NULL)
|
||||||
|
free(wsrc_);
|
||||||
|
|
||||||
|
*output = (uint16_t*)ret_;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int valid_d_char(char c)
|
static int valid_d_char(char c)
|
||||||
{
|
{
|
||||||
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
|
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
|
||||||
@ -1225,12 +1342,13 @@ uint16_t *ucsdup(const uint16_t *str)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Although each character is 2 bytes, we actually compare byte-by-byte
|
* Although each character is 2 bytes, we actually compare byte-by-byte
|
||||||
* (thats what the spec says).
|
* because the words are big-endian. Comparing possibly swapped words
|
||||||
|
* would make the sorting order depend on the machine byte order.
|
||||||
*/
|
*/
|
||||||
int ucscmp(const uint16_t *s1, const uint16_t *s2)
|
int ucscmp(const uint16_t *s1, const uint16_t *s2)
|
||||||
{
|
{
|
||||||
const char *s = (const char*)s1;
|
const uint8_t *s = (const uint8_t*)s1;
|
||||||
const char *t = (const char*)s2;
|
const uint8_t *t = (const uint8_t*)s2;
|
||||||
size_t len1 = ucslen(s1);
|
size_t len1 = ucslen(s1);
|
||||||
size_t len2 = ucslen(s2);
|
size_t len2 = ucslen(s2);
|
||||||
size_t i, len = MIN(len1, len2) * 2;
|
size_t i, len = MIN(len1, len2) * 2;
|
||||||
@ -1354,6 +1472,18 @@ void iso_bb(uint8_t *buf, uint32_t num, int bytes)
|
|||||||
iso_msb(buf+bytes, num, bytes);
|
iso_msb(buf+bytes, num, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* An alternative to iso_lsb() which advances the write pointer
|
||||||
|
*/
|
||||||
|
int iso_lsb_to_buf(char **wpt, uint32_t value, int bytes, int flag)
|
||||||
|
{
|
||||||
|
int b, bits;
|
||||||
|
|
||||||
|
bits = bytes * 8;
|
||||||
|
for (b = 0; b < bits; b += 8)
|
||||||
|
*((unsigned char *) ((*wpt)++)) = (value >> b) & 0xff;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t iso_read_lsb(const uint8_t *buf, int bytes)
|
uint32_t iso_read_lsb(const uint8_t *buf, int bytes)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -2063,4 +2193,19 @@ void *iso_alloc_mem(size_t size, size_t count, int flag)
|
|||||||
iso_msg_submit(-1, ISO_OUT_OF_MEM, 0, "Out of virtual memory");
|
iso_msg_submit(-1, ISO_OUT_OF_MEM, 0, "Out of virtual memory");
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t iso_ntohs(uint16_t v)
|
||||||
|
{
|
||||||
|
return iso_read_msb((uint8_t *) &v, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t iso_htons(uint16_t v)
|
||||||
|
{
|
||||||
|
uint16_t ret;
|
||||||
|
|
||||||
|
iso_msb((uint8_t *) &ret, (uint32_t) v, 2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,22 @@ int str2ascii(const char *icharset, const char *input, char **output);
|
|||||||
*/
|
*/
|
||||||
int str2ucs(const char *icharset, const char *input, uint16_t **output);
|
int str2ucs(const char *icharset, const char *input, uint16_t **output);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a given string from any input charset to UTF-16BE charset,
|
||||||
|
* used for HFS+ file identifiers.
|
||||||
|
* (UTF-16 differs from older UCS-2 by having multi word characters.)
|
||||||
|
*
|
||||||
|
* @param icharset
|
||||||
|
* Input charset. Must be supported by iconv
|
||||||
|
* @param input
|
||||||
|
* Input string
|
||||||
|
* @param output
|
||||||
|
* Location where the pointer to the ouput string will be stored
|
||||||
|
* @return
|
||||||
|
* 1 on success, < 0 on error
|
||||||
|
*/
|
||||||
|
int str2utf16be(const char *icharset, const char *input, uint16_t **output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a level 1 directory identifier.
|
* Create a level 1 directory identifier.
|
||||||
*
|
*
|
||||||
@ -232,6 +248,10 @@ void iso_lsb(uint8_t *buf, uint32_t num, int bytes);
|
|||||||
void iso_msb(uint8_t *buf, uint32_t num, int bytes);
|
void iso_msb(uint8_t *buf, uint32_t num, int bytes);
|
||||||
void iso_bb(uint8_t *buf, uint32_t num, int bytes);
|
void iso_bb(uint8_t *buf, uint32_t num, int bytes);
|
||||||
|
|
||||||
|
/* An alternative to iso_lsb() which advances the write pointer
|
||||||
|
*/
|
||||||
|
int iso_lsb_to_buf(char **wpt, uint32_t value, int bytes, int flag);
|
||||||
|
|
||||||
uint32_t iso_read_lsb(const uint8_t *buf, int bytes);
|
uint32_t iso_read_lsb(const uint8_t *buf, int bytes);
|
||||||
uint32_t iso_read_msb(const uint8_t *buf, int bytes);
|
uint32_t iso_read_msb(const uint8_t *buf, int bytes);
|
||||||
|
|
||||||
@ -543,6 +563,12 @@ int checksum_md5_xinfo_func(void *data, int flag);
|
|||||||
*/
|
*/
|
||||||
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
|
* iso_hfsplus_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
||||||
|
* iso_node_xinfo_make_clonable()
|
||||||
|
*/
|
||||||
|
int iso_hfsplus_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -567,4 +593,12 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* To avoid the need to include more system header files */
|
||||||
|
uint16_t iso_ntohs(uint16_t v);
|
||||||
|
uint16_t iso_htons(uint16_t v);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_UTIL_H_*/
|
#endif /*LIBISO_UTIL_H_*/
|
||||||
|
Reference in New Issue
Block a user