[iso] improve El Torito image handling

* Update to latest libcdio proposal and fix incorrect image size.
* Also remove unnecessary calls in packme.cmd.
This commit is contained in:
Pete Batard 2024-01-24 17:51:40 +00:00
parent f6fd520d2a
commit 018ed3414b
No known key found for this signature in database
GPG Key ID: 38E0CF5E69EDD671
6 changed files with 130 additions and 47 deletions

View File

@ -86,16 +86,14 @@ exiftool -s3 -*InternalName* rufus_x64.exe | findstr /C:"BETA" 1>nul && (
) )
rem Populate the version from the executable rem Populate the version from the executable
setlocal EnableDelayedExpansion
if "%VERSION_OVERRIDE%"=="" ( if "%VERSION_OVERRIDE%"=="" (
exiftool -s3 -*FileVersionNumber* rufus_x64.exe > version.txt exiftool -s3 -*FileVersionNumber* rufus_x64.exe > version.txt
set /p VERSION=<version.txt set /p VERSION=<version.txt
del version.txt del version.txt
)else ( ) else (
echo WARNING: Forcing version to %VERSION_OVERRIDE% echo WARNING: Forcing version to %VERSION_OVERRIDE%
set VERSION=%VERSION_OVERRIDE% set VERSION=%VERSION_OVERRIDE%
) )
setlocal DisableDelayedExpansion
echo Will create %VERSION% AppStore Bundle echo Will create %VERSION% AppStore Bundle
pause pause

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2003-2008, 2012-2013, 2017 Copyright (C) 2003-2008, 2012-2013, 2017, 2023-2024
Rocky Bernstein <rocky@gnu.org> Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
@ -27,7 +27,7 @@
* filesystem library; applications include this. * filesystem library; applications include this.
* *
* See also the ISO-9660 specification. The freely available European * 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 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 refer to the enumeration value names such as in a debugger
expression and get something. With the more common a \#define 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 { extern enum iso_enum1_s {
ISO_PVD_SECTOR = 16, /**< Sector of Primary Volume Descriptor. */ ISO_PVD_SECTOR = 16, /**< Sector of Primary Volume Descriptor. */
@ -93,8 +93,9 @@ extern enum iso_enum1_s {
preparer id. */ preparer id. */
MAX_ISOPATHNAME = 255, /**< Maximum number of characters in the MAX_ISOPATHNAME = 255, /**< Maximum number of characters in the
entire ISO 9660 filename. */ 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; } iso_enums1;
/*! An enumeration for some of the ISO_* \#defines below. This isn't /*! 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. \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 the primary descriptor but two unused fields, "unused1" and "unused3
become "flags and "escape_sequences" respectively. become "flags and "escape_sequences" respectively.
*/ */
@ -531,7 +532,7 @@ struct iso9660_br_s {
uint16_t load_seg; /**< Load segment for x86 */ uint16_t load_seg; /**< Load segment for x86 */
uint8_t system_type; /**< System type - 0 for x86 */ uint8_t system_type; /**< System type - 0 for x86 */
uint8_t unused1; 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 */ uint32_t image_lsn; /**< Start address of the image */
uint8_t unused2[20]; uint8_t unused2[20];
} GNUC_PACKED; } GNUC_PACKED;
@ -582,7 +583,7 @@ struct iso9660_stat_s { /* big endian!! */
/* Multi-extent aware size, in bytes. /* Multi-extent aware size, in bytes.
It is guaranteed that the bytes are stored as gapless string in a 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. starting at iso9660_stat_s.lsn.
Data files which do not fulfil this promise cause a warning message Data files which do not fulfil this promise cause a warning message
and are not represented by this type of struct. 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 contained in a file format that libiso9660 doesn't know natively
(or knows imperfectly.) (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 for STANDARD_ID and use that to set the eventual offset to adjust
by (as long as that is <= i_fuzz). by (as long as that is <= i_fuzz).
@ -683,7 +684,7 @@ typedef struct _iso9660_s iso9660_t;
uint16_t i_fuzz); 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 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). 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. tm will reported in GMT.
*/ */
bool iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime, 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 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 number. For example, mydir/file.ext -> MYDIR/FILE.EXT;1 for version
1. The resulting ISO-9660 pathname is returned. 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 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". to consider before giving up and returning "dunno".
"dunno" can also be returned if there was some error encountered "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); 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); bool iso9660_ifs_is_xa (const iso9660_t * p_iso);

View File

@ -105,6 +105,12 @@ _cdio_memdup (const void *mem, size_t count);
char * char *
_cdio_strdup_upper (const char str[]); _cdio_strdup_upper (const char str[]);
int
_cdio_stricmp(const char str1[], const char str2[]);
int
_cdio_strnicmp(const char str1[], const char str2[], size_t count);
/*! Duplicate path and make it platform compliant. Typically needed for /*! Duplicate path and make it platform compliant. Typically needed for
MinGW/MSYS where a "/c/..." path must be translated to "c:/..." for MinGW/MSYS where a "/c/..." path must be translated to "c:/..." for
use with fopen(), etc. Returned string must be freed by the caller use with fopen(), etc. Returned string must be freed by the caller

View File

@ -142,6 +142,35 @@ _cdio_strdup_upper (const char str[])
return new_str; return new_str;
} }
int
_cdio_stricmp (const char str1[], const char str2[])
{
if (str1 && str2) {
int c1, c2;
do {
c1 = tolower((unsigned char)*str1++);
c2 = tolower((unsigned char)*str2++);
} while (c1 == c2 && c1 != '\0');
return c1 - c2;
} else return (str1 != str2);
}
int
_cdio_strnicmp(const char str1[], const char str2[], size_t count)
{
if (str1 && str2) {
int c1 = 0, c2 = 0;
size_t i;
for (i = 0; i < count; i++) {
c1 = tolower((unsigned char)*str1++);
c2 = tolower((unsigned char)*str2++);
if (c1 != c2 || c1 == '\0')
break;
}
return c1 - c2;
} else return (str1 != str2);
}
/* Convert MinGW/MSYS paths that start in "/c/..." to "c:/..." /* Convert MinGW/MSYS paths that start in "/c/..." to "c:/..."
so that they can be used with fopen(), stat(), etc. so that they can be used with fopen(), stat(), etc.
Returned string must be freed by the caller using cdio_free().*/ Returned string must be freed by the caller using cdio_free().*/

View File

@ -1,6 +1,7 @@
/* /*
Copyright (C) 2003-2008, 2011-2015, 2017 Rocky Bernstein <rocky@gnu.org> Copyright (C) 2003-2008, 2011-2015, 2017, 2024
Copyright (C) 2018, 2020 Pete Batard <pete@akeo.ie> Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2018, 2020, 2024 Pete Batard <pete@akeo.ie>
Copyright (C) 2018 Thomas Schmitt <scdbackup@gmx.net> Copyright (C) 2018 Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
@ -59,6 +60,7 @@
#include "_cdio_stdio.h" #include "_cdio_stdio.h"
#include "cdio_private.h" #include "cdio_private.h"
/* Maximum number of El-Torito boot images we keep an index for */
#define MAX_BOOT_IMAGES 8 #define MAX_BOOT_IMAGES 8
/** Implementation of iso9660_t type */ /** Implementation of iso9660_t type */
@ -87,7 +89,8 @@ struct _iso9660_s {
*/ */
struct { struct {
uint32_t lsn; /**< Start LSN of an El-Torito bootable image */ 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]; } boot_img[MAX_BOOT_IMAGES];
int i_fuzzy_offset; /**< Adjustment in bytes to make ISO_STANDARD_ID int i_fuzzy_offset; /**< Adjustment in bytes to make ISO_STANDARD_ID
("CD001") come out as ISO_PVD_SECTOR ("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 */ /* Check for an El-Torito boot volume descriptor */
if (ISO_VD_BOOT_RECORD == from_711(p_svd.type) && if (ISO_VD_BOOT_RECORD == from_711(p_svd.type) &&
(memcmp(p_brvd->system_id, EL_TORITO_ID, ISO_MAX_SYSTEM_ID) == 0)) { (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)]; 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) { if (iso9660_iso_seek_read(p_iso, &br, p_brvd->boot_catalog_sector, 1) == ISO_BLOCKSIZE) {
for (j = 0, k = 0; 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. Convert a directory record name to a 0-terminated string.
One of parameters alloc_result and cpy_result should be non-NULL to take One of parameters alloc_result and cpy_result should be non-NULL to take
the result. the result.
*/ */
static bool static bool
_iso9660_recname_to_cstring(const char *src, size_t src_len, _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; unsigned offset = 0;
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
uint32_t blocks; uint32_t blocks;
int ret, cmp; int ret, cmp;
iso9660_stat_t *p_stat = NULL; iso9660_stat_t *p_stat = NULL;
iso9660_dir_t *p_iso9660_dir = 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_stat_t *
iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[]) iso9660_ifs_stat_translate (iso9660_t *p_iso, const char psz_path[])
{ {
/* Special case for virtual El-Torito boot images ('[BOOT]/#.img') */ /* Special case for virtual El-Torito boot images ('/[BOOT]/#-Boot-NoEmul.img') */
if (psz_path && (strncmp(psz_path, "[BOOT]/", 7) == 0)) { if (psz_path && p_iso && p_iso->boot_img[0].lsn != 0) {
int index = psz_path[7] - '0'; /* Work on a path without leading slash */
iso9660_stat_t* p_stat; const char* path = (psz_path[0] == '/') ? &psz_path[1] : psz_path;
if (strlen(psz_path) < 8) if ((_cdio_strnicmp(path, "[BOOT]/", 7) == 0) &&
return NULL; (_cdio_stricmp(&path[8], "-Boot-NoEmul.img") == 0)) {
if ((psz_path[7] < '0') || (psz_path[7] > '0' + MAX_BOOT_IMAGES - 1)) int index = path[7] - '0';
return NULL; iso9660_stat_t* p_stat;
if (p_iso->boot_img[index].lsn == 0 || p_iso->boot_img[index].num_sectors == 0) if (strlen(path) < 24)
return NULL; return NULL;
p_stat = calloc(1, sizeof(iso9660_stat_t) + strlen(psz_path)); cdio_assert(MAX_BOOT_IMAGES <= 10);
if (!p_stat) { if ((path[7] < '0') || (path[7] > '0' + MAX_BOOT_IMAGES - 1))
cdio_warn("Couldn't calloc(1, %d)", (int)sizeof(iso9660_stat_t)); return NULL;
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, return fs_stat_translate(p_iso, (stat_root_t *) _ifs_stat_root,
@ -1623,6 +1632,7 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
CdioISO9660FileList_t * CdioISO9660FileList_t *
iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
{ {
int i;
iso9660_dir_t *p_iso9660_dir; iso9660_dir_t *p_iso9660_dir;
iso9660_stat_t *p_iso9660_stat = NULL; iso9660_stat_t *p_iso9660_stat = NULL;
iso9660_stat_t *p_stat; iso9660_stat_t *p_stat;
@ -1630,6 +1640,30 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
if (!p_iso) return NULL; if (!p_iso) return NULL;
if (!psz_path) 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); p_stat = iso9660_ifs_stat (p_iso, psz_path);
if (!p_stat) return NULL; 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; const size_t dirbuf_len = blocks * ISO_BLOCKSIZE;
bool skip_following_extents = false; 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) if (!dirbuf_len)
{ {
cdio_warn("Invalid directory buffer sector size %u", blocks); cdio_warn("Invalid directory buffer sector size %u", blocks);

View File

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326 IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 4.4.2104" CAPTION "Rufus 4.4.2105"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0 FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -392,8 +392,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,4,2104,0 FILEVERSION 4,4,2105,0
PRODUCTVERSION 4,4,2104,0 PRODUCTVERSION 4,4,2105,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -411,13 +411,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie" VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting" VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.4.2104" VALUE "FileVersion", "4.4.2105"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.4.exe" VALUE "OriginalFilename", "rufus-4.4.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.4.2104" VALUE "ProductVersion", "4.4.2105"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"