mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[iso] add basic El-Torito image parsing to libcdio
* Based on El-Torito specs found at https://pdos.csail.mit.edu/6.828/2014/readings/boot-cdrom.pdf. * Follows 7-zip's virtual '[BOOT]/#...' naming conventions (though we don't check for the full name). * Limited to 8 NoEmul images.
This commit is contained in:
parent
2cebf914fd
commit
ae6732c07b
3 changed files with 87 additions and 7 deletions
|
@ -162,6 +162,7 @@ extern enum iso_vd_enum_s {
|
|||
extern const char ISO_STANDARD_ID[sizeof("CD001")-1];
|
||||
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
#define EL_TORITO_ID "EL TORITO SPECIFICATION\0\0\0\0\0\0\0\0\0"
|
||||
|
||||
#define CDIO_EXTENT_BLOCKS(size) ((size + (ISO_BLOCKSIZE - 1)) / ISO_BLOCKSIZE)
|
||||
|
||||
|
@ -506,6 +507,37 @@ struct iso9660_svd_s {
|
|||
|
||||
typedef struct iso9660_svd_s iso9660_svd_t;
|
||||
|
||||
/*!
|
||||
\brief ISO-9660 Boot Record Volume Descriptor.
|
||||
*/
|
||||
struct iso9660_brvd_s {
|
||||
uint8_t type; /**< ISO_VD_BOOT_RECORD - 0 */
|
||||
char id[5]; /**< ISO_STANDARD_ID "CD001" */
|
||||
uint8_t version; /**< value 1 for El Torito */
|
||||
char system_id[ISO_MAX_SYSTEM_ID]; /**< Boot system ID */
|
||||
uint8_t unused1[32]; /**< unused - value 0 */
|
||||
uint32_t boot_catalog_sector; /**< first sector of boot catalog */
|
||||
uint8_t unused2[1973]; /**< Unused - value 0 */
|
||||
} GNUC_PACKED;
|
||||
|
||||
typedef struct iso9660_brvd_s iso9660_brvd_t;
|
||||
|
||||
/*!
|
||||
\brief ISO-9660 Boot Record Volume Descriptor.
|
||||
*/
|
||||
struct iso9660_br_s {
|
||||
uint8_t boot_id; /**< Boot indicator - 0x88 */
|
||||
uint8_t media_type; /**< Boot media type - 0 for no emul. */
|
||||
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 */
|
||||
uint32_t image_lsn; /**< Start address of the image */
|
||||
uint8_t unused2[20];
|
||||
} GNUC_PACKED;
|
||||
|
||||
typedef struct iso9660_br_s iso9660_br_t;
|
||||
|
||||
PRAGMA_END_PACKED
|
||||
|
||||
/*! \brief A data type for a list of ISO9660
|
||||
|
@ -582,7 +614,8 @@ extern enum iso_extension_enum_s {
|
|||
ISO_EXTENSION_JOLIET_LEVEL2 = 0x02,
|
||||
ISO_EXTENSION_JOLIET_LEVEL3 = 0x04,
|
||||
ISO_EXTENSION_ROCK_RIDGE = 0x08,
|
||||
ISO_EXTENSION_HIGH_SIERRA = 0x10
|
||||
ISO_EXTENSION_HIGH_SIERRA = 0x10,
|
||||
ISO_EXTENSION_EL_TORITO = 0x20
|
||||
} iso_extension_enums;
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
#include "_cdio_stdio.h"
|
||||
#include "cdio_private.h"
|
||||
|
||||
#define MAX_BOOT_IMAGES 8
|
||||
|
||||
/** Implementation of iso9660_t type */
|
||||
struct _iso9660_s {
|
||||
cdio_header_t header; /**< Internal header - MUST come first. */
|
||||
|
@ -83,6 +85,10 @@ struct _iso9660_s {
|
|||
be CDIO_CD_FRAMESIZE_RAW (2352) or
|
||||
M2RAW_SECTOR_SIZE (2336).
|
||||
*/
|
||||
struct {
|
||||
uint32_t lsn; /**< Start LSN of an El-Torito bootable image */
|
||||
uint32_t num_sectors; /**< Number of sectors of a 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
|
||||
(frame 16). Normally this should be 0
|
||||
|
@ -505,7 +511,8 @@ iso9660_ifs_read_superblock (iso9660_t *p_iso,
|
|||
iso_extension_mask_t iso_extension_mask)
|
||||
{
|
||||
iso9660_svd_t p_svd; /* Secondary volume descriptor. */
|
||||
int i;
|
||||
iso9660_brvd_t* p_brvd = (iso9660_brvd_t*)&p_svd; /* Boot record volume descriptor. */
|
||||
int i, j, k;
|
||||
|
||||
if (!p_iso || !iso9660_ifs_read_pvd(p_iso, &(p_iso->pvd)))
|
||||
return false;
|
||||
|
@ -516,6 +523,24 @@ iso9660_ifs_read_superblock (iso9660_t *p_iso,
|
|||
for (i=1; (0 != iso9660_iso_seek_read (p_iso, &p_svd, ISO_PVD_SECTOR+i, 1)); i++) {
|
||||
if (ISO_VD_END == from_711(p_svd.type) ) /* Last SVD */
|
||||
break;
|
||||
if (iso_extension_mask & ISO_EXTENSION_EL_TORITO) {
|
||||
/* 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 */
|
||||
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;
|
||||
j < (ISO_BLOCKSIZE / sizeof(iso9660_br_t)) && k < MAX_BOOT_IMAGES;
|
||||
j++) {
|
||||
if (br[j].boot_id == 0x88 && br[j].media_type == 0) {
|
||||
p_iso->boot_img[k].lsn = br[j].image_lsn;
|
||||
p_iso->boot_img[k++].num_sectors = br[j].num_sectors;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ISO_VD_SUPPLEMENTARY == from_711(p_svd.type) ) {
|
||||
/* We're only interested in Joliet => make sure the SVD isn't overwritten */
|
||||
if (p_iso->u_joliet_level == 0)
|
||||
|
@ -1441,6 +1466,28 @@ 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;
|
||||
}
|
||||
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,
|
||||
(stat_traverse_t *) _fs_iso_stat_traverse,
|
||||
psz_path);
|
||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Rufus 4.4.2099"
|
||||
CAPTION "Rufus 4.4.2100"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -392,8 +392,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,4,2099,0
|
||||
PRODUCTVERSION 4,4,2099,0
|
||||
FILEVERSION 4,4,2100,0
|
||||
PRODUCTVERSION 4,4,2100,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -411,13 +411,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "4.4.2099"
|
||||
VALUE "FileVersion", "4.4.2100"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2024 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
VALUE "OriginalFilename", "rufus-4.4.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "4.4.2099"
|
||||
VALUE "ProductVersion", "4.4.2100"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Reference in a new issue