-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[iso] improve El Torito image handling
* Update to latest libcdio proposal and fix incorrect image size. * Also remove unnecessary calls in packme.cmd.
- Loading branch information
Showing
6 changed files
with
130 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
Copyright (C) 2003-2008, 2012-2013, 2017 | ||
Copyright (C) 2003-2008, 2012-2013, 2017, 2023-2024 | ||
Rocky Bernstein <[email protected]> | ||
Copyright (C) 2000 Herbert Valerio Riedel <[email protected]> | ||
|
@@ -27,7 +27,7 @@ | |
* filesystem library; applications include this. | ||
* | ||
* See also the ISO-9660 specification. The freely available European | ||
* equivalant standard is called ECMA-119. | ||
* equivalent standard is called ECMA-119. | ||
*/ | ||
|
||
|
||
|
@@ -78,7 +78,7 @@ typedef char dchar_t; /*! See section 7.4.1 */ | |
program; things are done this way so that in a debugger one can to | ||
refer to the enumeration value names such as in a debugger | ||
expression and get something. With the more common a \#define | ||
mechanism, the name/value assocation is lost at run time. | ||
mechanism, the name/value association is lost at run time. | ||
*/ | ||
extern enum iso_enum1_s { | ||
ISO_PVD_SECTOR = 16, /**< Sector of Primary Volume Descriptor. */ | ||
|
@@ -93,8 +93,9 @@ extern enum iso_enum1_s { | |
preparer id. */ | ||
MAX_ISOPATHNAME = 255, /**< Maximum number of characters in the | ||
entire ISO 9660 filename. */ | ||
ISO_BLOCKSIZE = 2048 /**< Number of bytes in an ISO 9660 block. */ | ||
|
||
ISO_BLOCKSIZE = 2048, /**< Number of bytes in an ISO 9660 block. */ | ||
VIRTUAL_SECTORSIZE = 512 /**< Number of bytes in an El Torito virtual | ||
image sector */ | ||
} iso_enums1; | ||
|
||
/*! An enumeration for some of the ISO_* \#defines below. This isn't | ||
|
@@ -396,7 +397,7 @@ typedef struct iso9660_pvd_s iso9660_pvd_t; | |
/*! | ||
\brief ISO-9660 Supplementary Volume Descriptor. | ||
This is used for Joliet Extentions and is almost the same as the | ||
This is used for Joliet Extensions and is almost the same as the | ||
the primary descriptor but two unused fields, "unused1" and "unused3 | ||
become "flags and "escape_sequences" respectively. | ||
*/ | ||
|
@@ -531,7 +532,7 @@ struct iso9660_br_s { | |
uint16_t load_seg; /**< Load segment for x86 */ | ||
uint8_t system_type; /**< System type - 0 for x86 */ | ||
uint8_t unused1; | ||
uint16_t num_sectors; /**< Sector count of the image */ | ||
uint16_t num_sectors; /**< Virtual sectors count of the image */ | ||
uint32_t image_lsn; /**< Start address of the image */ | ||
uint8_t unused2[20]; | ||
} GNUC_PACKED; | ||
|
@@ -582,7 +583,7 @@ struct iso9660_stat_s { /* big endian!! */ | |
/* Multi-extent aware size, in bytes. | ||
It is guaranteed that the bytes are stored as gapless string in a | ||
continguous sequence of blocks. I.e. they can be read sequentially | ||
contiguous sequence of blocks. I.e. they can be read sequentially | ||
starting at iso9660_stat_s.lsn. | ||
Data files which do not fulfil this promise cause a warning message | ||
and are not represented by this type of struct. | ||
|
@@ -671,7 +672,7 @@ typedef struct _iso9660_s iso9660_t; | |
contained in a file format that libiso9660 doesn't know natively | ||
(or knows imperfectly.) | ||
Some tolerence allowed for positioning the ISO 9660 image. We scan | ||
Some tolerance allowed for positioning the ISO 9660 image. We scan | ||
for STANDARD_ID and use that to set the eventual offset to adjust | ||
by (as long as that is <= i_fuzz). | ||
|
@@ -683,7 +684,7 @@ typedef struct _iso9660_s iso9660_t; | |
uint16_t i_fuzz); | ||
|
||
/*! | ||
Open an ISO 9660 image for reading with some tolerence for positioning | ||
Open an ISO 9660 image for reading with some tolerance for positioning | ||
of the ISO9660 image. We scan for ISO_STANDARD_ID and use that to set | ||
the eventual offset to adjust by (as long as that is <= i_fuzz). | ||
|
@@ -799,7 +800,7 @@ typedef struct _iso9660_s iso9660_t; | |
tm will reported in GMT. | ||
*/ | ||
bool iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime, | ||
/*out*/ struct tm *tm); | ||
/*out*/ struct tm *p_tm); | ||
|
||
|
||
/*! | ||
|
@@ -890,7 +891,7 @@ typedef struct _iso9660_s iso9660_t; | |
|
||
/*! | ||
Take psz_path and a version number and turn that into a ISO-9660 | ||
pathname. (That's just the pathname followd by ";" and the version | ||
pathname. (That's just the pathname followed by ";" and the version | ||
number. For example, mydir/file.ext -> MYDIR/FILE.EXT;1 for version | ||
1. The resulting ISO-9660 pathname is returned. | ||
*/ | ||
|
@@ -1235,7 +1236,7 @@ lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr); | |
@param p_iso the ISO-9660 file image to get data from | ||
@param u_file_limit the maximimum number of (non-rock-ridge) files | ||
@param u_file_limit the maximum number of (non-rock-ridge) files | ||
to consider before giving up and returning "dunno". | ||
"dunno" can also be returned if there was some error encountered | ||
|
@@ -1311,7 +1312,7 @@ lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr); | |
void iso9660_set_evd (void *pd); | ||
|
||
/*! | ||
Return true if ISO 9660 image has extended attrributes (XA). | ||
Return true if ISO 9660 image has extended attributes (XA). | ||
*/ | ||
bool iso9660_ifs_is_xa (const iso9660_t * p_iso); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
Copyright (C) 2003-2008, 2011-2015, 2017 Rocky Bernstein <[email protected]> | ||
Copyright (C) 2018, 2020 Pete Batard <[email protected]> | ||
Copyright (C) 2003-2008, 2011-2015, 2017, 2024 | ||
Rocky Bernstein <[email protected]> | ||
Copyright (C) 2018, 2020, 2024 Pete Batard <[email protected]> | ||
Copyright (C) 2018 Thomas Schmitt <[email protected]> | ||
Copyright (C) 2001 Herbert Valerio Riedel <[email protected]> | ||
|
@@ -59,6 +60,7 @@ | |
#include "_cdio_stdio.h" | ||
#include "cdio_private.h" | ||
|
||
/* Maximum number of El-Torito boot images we keep an index for */ | ||
#define MAX_BOOT_IMAGES 8 | ||
|
||
/** Implementation of iso9660_t type */ | ||
|
@@ -87,7 +89,8 @@ struct _iso9660_s { | |
*/ | ||
struct { | ||
uint32_t lsn; /**< Start LSN of an El-Torito bootable image */ | ||
uint32_t num_sectors; /**< Number of sectors of a bootable image */ | ||
uint32_t num_sectors; /**< Number of virtual sectors occupied by the | ||
bootable image */ | ||
} boot_img[MAX_BOOT_IMAGES]; | ||
int i_fuzzy_offset; /**< Adjustment in bytes to make ISO_STANDARD_ID | ||
("CD001") come out as ISO_PVD_SECTOR | ||
|
@@ -527,7 +530,7 @@ iso9660_ifs_read_superblock (iso9660_t *p_iso, | |
/* Check for an El-Torito boot volume descriptor */ | ||
if (ISO_VD_BOOT_RECORD == from_711(p_svd.type) && | ||
(memcmp(p_brvd->system_id, EL_TORITO_ID, ISO_MAX_SYSTEM_ID) == 0)) { | ||
/* Perform very basic parsing of boot entries to fill an image table */ | ||
/* Perform basic parsing of boot entries to fill an image table */ | ||
iso9660_br_t br[ISO_BLOCKSIZE / sizeof(iso9660_br_t)]; | ||
if (iso9660_iso_seek_read(p_iso, &br, p_brvd->boot_catalog_sector, 1) == ISO_BLOCKSIZE) { | ||
for (j = 0, k = 0; | ||
|
@@ -823,7 +826,7 @@ _iso9660_is_rock_ridge_enabled(void* p_image) | |
/*! | ||
Convert a directory record name to a 0-terminated string. | ||
One of parameters alloc_result and cpy_result should be non-NULL to take | ||
the result. | ||
the result. | ||
*/ | ||
static bool | ||
_iso9660_recname_to_cstring(const char *src, size_t src_len, | ||
|
@@ -1261,7 +1264,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, | |
{ | ||
unsigned offset = 0; | ||
uint8_t *_dirbuf = NULL; | ||
uint32_t blocks; | ||
uint32_t blocks; | ||
int ret, cmp; | ||
iso9660_stat_t *p_stat = NULL; | ||
iso9660_dir_t *p_iso9660_dir = NULL; | ||
|
@@ -1466,26 +1469,32 @@ iso9660_fs_stat_translate (CdIo_t *p_cdio, const char psz_path[]) | |
iso9660_stat_t * | ||
iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[]) | ||
{ | ||
/* Special case for virtual El-Torito boot images ('[BOOT]/#.img') */ | ||
if (psz_path && (strncmp(psz_path, "[BOOT]/", 7) == 0)) { | ||
int index = psz_path[7] - '0'; | ||
iso9660_stat_t* p_stat; | ||
if (strlen(psz_path) < 8) | ||
return NULL; | ||
if ((psz_path[7] < '0') || (psz_path[7] > '0' + MAX_BOOT_IMAGES - 1)) | ||
return NULL; | ||
if (p_iso->boot_img[index].lsn == 0 || p_iso->boot_img[index].num_sectors == 0) | ||
return NULL; | ||
p_stat = calloc(1, sizeof(iso9660_stat_t) + strlen(psz_path)); | ||
if (!p_stat) { | ||
cdio_warn("Couldn't calloc(1, %d)", (int)sizeof(iso9660_stat_t)); | ||
return NULL; | ||
/* Special case for virtual El-Torito boot images ('/[BOOT]/#-Boot-NoEmul.img') */ | ||
if (psz_path && p_iso && p_iso->boot_img[0].lsn != 0) { | ||
/* Work on a path without leading slash */ | ||
const char* path = (psz_path[0] == '/') ? &psz_path[1] : psz_path; | ||
if ((_cdio_strnicmp(path, "[BOOT]/", 7) == 0) && | ||
(_cdio_stricmp(&path[8], "-Boot-NoEmul.img") == 0)) { | ||
int index = path[7] - '0'; | ||
iso9660_stat_t* p_stat; | ||
if (strlen(path) < 24) | ||
return NULL; | ||
cdio_assert(MAX_BOOT_IMAGES <= 10); | ||
if ((path[7] < '0') || (path[7] > '0' + MAX_BOOT_IMAGES - 1)) | ||
return NULL; | ||
if (p_iso->boot_img[index].lsn == 0 || p_iso->boot_img[index].num_sectors == 0) | ||
return NULL; | ||
p_stat = calloc(1, sizeof(iso9660_stat_t) + strlen(path)); | ||
if (!p_stat) { | ||
cdio_warn("Couldn't calloc(1, %d)", (int)sizeof(iso9660_stat_t)); | ||
return NULL; | ||
} | ||
p_stat->lsn = p_iso->boot_img[index].lsn; | ||
p_stat->total_size = p_iso->boot_img[index].num_sectors * VIRTUAL_SECTORSIZE; | ||
p_stat->type = _STAT_FILE; | ||
strcpy(p_stat->filename, path); | ||
return p_stat; | ||
} | ||
p_stat->lsn = p_iso->boot_img[index].lsn; | ||
p_stat->total_size = p_iso->boot_img[index].num_sectors * ISO_BLOCKSIZE; | ||
p_stat->type = _STAT_FILE; | ||
strcpy(p_stat->filename, psz_path); | ||
return p_stat; | ||
} | ||
|
||
return fs_stat_translate(p_iso, (stat_root_t *) _ifs_stat_root, | ||
|
@@ -1623,13 +1632,38 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[]) | |
CdioISO9660FileList_t * | ||
iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) | ||
{ | ||
int i; | ||
iso9660_dir_t *p_iso9660_dir; | ||
iso9660_stat_t *p_iso9660_stat = NULL; | ||
iso9660_stat_t *p_stat; | ||
|
||
if (!p_iso) return NULL; | ||
if (!psz_path) return NULL; | ||
|
||
/* List the virtual El-Torito images */ | ||
if (p_iso->boot_img[0].lsn != 0) { | ||
const char* path = (psz_path[0] == '/') ? &psz_path[1] : psz_path; | ||
if (_cdio_strnicmp(path, "[BOOT]", 6) == 0 && (path[6] == '\0' || path[6] == '/')) { | ||
CdioList_t* retval = _cdio_list_new(); | ||
for (i = 0; i < MAX_BOOT_IMAGES && p_iso->boot_img[i].lsn != 0; i++) { | ||
p_iso9660_stat = calloc(1, sizeof(iso9660_stat_t) + 18); | ||
if (!p_iso9660_stat) { | ||
cdio_warn("Couldn't calloc(1, %d)", (int)sizeof(iso9660_stat_t) + 18); | ||
break; | ||
} | ||
strcpy(p_iso9660_stat->filename, "#-Boot-NoEmul.img"); | ||
p_iso9660_stat->filename[0] = '0' + i; | ||
p_iso9660_stat->type = _STAT_FILE; | ||
p_iso9660_stat->lsn = p_iso->boot_img[i].lsn; | ||
p_iso9660_stat->total_size = p_iso->boot_img[i].num_sectors * VIRTUAL_SECTORSIZE; | ||
iso9660_get_ltime(&p_iso->pvd.creation_date, &p_iso9660_stat->tm); | ||
_cdio_list_append(retval, p_iso9660_stat); | ||
p_iso9660_stat = NULL; | ||
} | ||
return retval; | ||
} | ||
} | ||
|
||
p_stat = iso9660_ifs_stat (p_iso, psz_path); | ||
if (!p_stat) return NULL; | ||
|
||
|
@@ -1647,6 +1681,21 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) | |
const size_t dirbuf_len = blocks * ISO_BLOCKSIZE; | ||
bool skip_following_extents = false; | ||
|
||
/* Add the virtual El-Torito "[BOOT]" directory to root */ | ||
if (p_iso->boot_img[0].lsn != 0) { | ||
if (psz_path[0] == '\0' || (psz_path[0] == '/' && psz_path[1] == '\0')) { | ||
p_iso9660_stat = calloc(1, sizeof(iso9660_stat_t) + 7); | ||
if (p_iso9660_stat) { | ||
strcpy(p_iso9660_stat->filename, "[BOOT]"); | ||
p_iso9660_stat->type = _STAT_DIR; | ||
p_iso9660_stat->lsn = ISO_PVD_SECTOR + 1; | ||
iso9660_get_ltime(&p_iso->pvd.creation_date, &p_iso9660_stat->tm); | ||
_cdio_list_append(retval, p_iso9660_stat); | ||
p_iso9660_stat = NULL; | ||
} | ||
} | ||
} | ||
|
||
if (!dirbuf_len) | ||
{ | ||
cdio_warn("Invalid directory buffer sector size %u", blocks); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters