mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
parent
7463fa6da3
commit
77d319267f
8 changed files with 216 additions and 246 deletions
|
@ -654,6 +654,10 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
|
|||
_CDIO_LIST_FOREACH(p_entnode, p_entlist) {
|
||||
if (FormatStatus) goto out;
|
||||
p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode);
|
||||
if ((p_statbuf->rr.b3_rock == yep) && enable_rockridge) {
|
||||
if (p_statbuf->rr.u_su_fields & ISO_ROCK_SUF_PL)
|
||||
img_report.has_deep_directories = TRUE;
|
||||
}
|
||||
// Eliminate . and .. entries
|
||||
if ( (strcmp(p_statbuf->filename, ".") == 0)
|
||||
|| (strcmp(p_statbuf->filename, "..") == 0) )
|
||||
|
|
|
@ -190,12 +190,12 @@ typedef struct iso_rock_nm_s {
|
|||
|
||||
/*! Child link. See Section 4.1.5.1 */
|
||||
typedef struct iso_rock_cl_s {
|
||||
char location[1];
|
||||
iso733_t location;
|
||||
} GNUC_PACKED iso_rock_cl_t ;
|
||||
|
||||
/*! Parent link. See Section 4.1.5.2 */
|
||||
typedef struct iso_rock_pl_s {
|
||||
char location[1];
|
||||
iso733_t location;
|
||||
} GNUC_PACKED iso_rock_pl_t ;
|
||||
|
||||
/*! These are the bits and their meanings for flags in the TF structure. */
|
||||
|
@ -264,9 +264,29 @@ typedef struct iso_extension_record_s {
|
|||
iso_rock_cl_t CL; /**< Rock Ridge child link */
|
||||
iso_rock_pl_t PL; /**< Rock Ridge parent link */
|
||||
iso_rock_tf_t TF; /**< Rock Ridge timestamp(s) for a file */
|
||||
iso_rock_sf_t SF; /**< Rock Ridge sparse file */
|
||||
} u;
|
||||
} GNUC_PACKED iso_extension_record_t;
|
||||
|
||||
/* Bits for the u_su_fields of iso_rock_statbuf_t */
|
||||
#define ISO_ROCK_SUF_SP 0x00000001
|
||||
#define ISO_ROCK_SUF_ER 0x00000002
|
||||
#define ISO_ROCK_SUF_CE 0x00000004
|
||||
#define ISO_ROCK_SUF_PX 0x00000008
|
||||
#define ISO_ROCK_SUF_PN 0x00000010
|
||||
#define ISO_ROCK_SUF_SL 0x00000020
|
||||
#define ISO_ROCK_SUF_NM 0x00000040
|
||||
#define ISO_ROCK_SUF_TF 0x00000080
|
||||
#define ISO_ROCK_SUF_CL 0x00000100
|
||||
#define ISO_ROCK_SUF_PL 0x00000200
|
||||
#define ISO_ROCK_SUF_RE 0x00000400
|
||||
#define ISO_ROCK_SUF_SF 0x00000800
|
||||
|
||||
#define ISO_ROCK_SUF_FORMAL (ISO_ROCK_SUF_ER | ISO_ROCK_SUF_PX | ISO_ROCK_SUF_PN | \
|
||||
ISO_ROCK_SUF_SL | ISO_ROCK_SUF_NM | ISO_ROCK_SUF_CL | \
|
||||
ISO_ROCK_SUF_PL | ISO_ROCK_SUF_RE | ISO_ROCK_SUF_TF | \
|
||||
ISO_ROCK_SUF_SF)
|
||||
|
||||
typedef struct iso_rock_time_s {
|
||||
bool b_used; /**< If true, field has been set and is valid.
|
||||
Otherwise remaning fields are meaningless. */
|
||||
|
@ -309,16 +329,20 @@ typedef struct iso_rock_statbuf_s {
|
|||
uint32_t i_rdev; /**< the upper 16-bits is major device
|
||||
number, the lower 16-bits is the
|
||||
minor device number */
|
||||
uint32_t u_su_fields; /**< System Use field attributes */
|
||||
|
||||
} iso_rock_statbuf_t;
|
||||
|
||||
PRAGMA_END_PACKED
|
||||
|
||||
/*! return length of name field; 0: not found, -1: to be ignored */
|
||||
int get_rock_ridge_filename(iso9660_dir_t * de, /*out*/ char * retname,
|
||||
int get_rock_ridge_filename(iso9660_dir_t * de,
|
||||
/*in*/ void * p_iso,
|
||||
/*out*/ char * retname,
|
||||
/*out*/ iso9660_stat_t *p_stat);
|
||||
|
||||
int parse_rock_ridge_stat(iso9660_dir_t *de, /*out*/ iso9660_stat_t *p_stat);
|
||||
int parse_rock_ridge_stat(iso9660_dir_t *de,
|
||||
/*out*/ iso9660_stat_t *p_stat);
|
||||
|
||||
/*!
|
||||
Returns POSIX mode bitstring for a given file.
|
||||
|
|
|
@ -55,7 +55,7 @@ static inline char *libcdio_strndup(const char *s, size_t n)
|
|||
if (!result)
|
||||
return 0;
|
||||
result[len] = '\0';
|
||||
return (char *) strncpy (result, s, len);
|
||||
return (char *) memcpy (result, s, len);
|
||||
}
|
||||
#endif /*HAVE_STRNDUP*/
|
||||
|
||||
|
@ -467,13 +467,23 @@ extern "C" {
|
|||
|
||||
} cdio_funcs_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t u_type;
|
||||
uint16_t u_flags;
|
||||
} cdio_header_t;
|
||||
|
||||
#define CDIO_HEADER_TYPE_CDIO 0x0000
|
||||
#define CDIO_HEADER_TYPE_ISO 0x0001
|
||||
|
||||
#define CDIO_HEADER_FLAGS_DISABLE_RR_DD 0x0001
|
||||
|
||||
/*! Implementation of CdIo type */
|
||||
struct _CdIo {
|
||||
cdio_header_t header; /**< Internal header - MUST come first. */
|
||||
driver_id_t driver_id; /**< Particular driver opened. */
|
||||
cdio_funcs_t op; /**< driver-specific routines handling
|
||||
implementation*/
|
||||
void *env; /**< environment. Passed to routine above. */
|
||||
implementation. */
|
||||
void* env; /**< environment. Passed to routine above. */
|
||||
};
|
||||
|
||||
/* This is used in drivers that must keep their own internal
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
|
||||
/** Implementation of iso9660_t type */
|
||||
struct _iso9660_s {
|
||||
cdio_header_t header; /**< Internal header - MUST come first. */
|
||||
CdioDataSource_t *stream; /**< Stream pointer */
|
||||
bool_3way_t b_xa; /**< true if has XA attributes. */
|
||||
bool_3way_t b_mode2; /**< true if has mode 2, false for mode 1. */
|
||||
|
@ -93,7 +94,6 @@ struct _iso9660_s {
|
|||
different.
|
||||
*/
|
||||
bool b_have_superblock; /**< Superblock has been read in? */
|
||||
|
||||
};
|
||||
|
||||
static long int iso9660_seek_read_framesize (const iso9660_t *p_iso,
|
||||
|
@ -174,8 +174,10 @@ iso9660_open_ext_private (const char *psz_path,
|
|||
{
|
||||
iso9660_t *p_iso = (iso9660_t *) calloc(1, sizeof(iso9660_t)) ;
|
||||
|
||||
if (!p_iso) return NULL;
|
||||
if (!p_iso)
|
||||
return NULL;
|
||||
|
||||
p_iso->header.u_type = CDIO_HEADER_TYPE_ISO;
|
||||
p_iso->stream = cdio_stdio_new( psz_path );
|
||||
if (NULL == p_iso->stream)
|
||||
goto error;
|
||||
|
@ -778,19 +780,34 @@ iso9660_check_dir_block_end(iso9660_dir_t *p_iso9660_dir, unsigned *offset)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_iso9660_is_rock_ridge_enabled(void* p_image)
|
||||
{
|
||||
cdio_header_t* p_header = (cdio_header_t*)p_image;
|
||||
|
||||
if (!p_header)
|
||||
return false;
|
||||
if (p_header->u_type == CDIO_HEADER_TYPE_ISO) {
|
||||
iso9660_t* p_iso = (iso9660_t*)p_image;
|
||||
return (p_iso->iso_extension_mask & ISO_EXTENSION_ROCK_RIDGE);
|
||||
}
|
||||
/* Rock Ridge is always enabled for other types */
|
||||
return true;
|
||||
}
|
||||
|
||||
static iso9660_stat_t *
|
||||
_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
|
||||
iso9660_stat_t *last_p_stat,
|
||||
bool_3way_t b_xa, uint8_t u_joliet_level)
|
||||
void* p_image,
|
||||
bool_3way_t b_xa,
|
||||
uint8_t u_joliet_level)
|
||||
{
|
||||
uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir);
|
||||
iso711_t i_fname;
|
||||
unsigned int stat_len;
|
||||
iso9660_stat_t *p_stat = last_p_stat;
|
||||
char rr_fname[256] = "";
|
||||
int i_rr_fname;
|
||||
int i_rr_fname = 0;
|
||||
lsn_t extent_lsn;
|
||||
bool first_extent;
|
||||
|
||||
|
@ -814,6 +831,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
|
|||
}
|
||||
p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY)
|
||||
? _STAT_DIR : _STAT_FILE;
|
||||
/* Ignore Rock Ridge Deep Directory RE entries */
|
||||
if (p_stat->rr.u_su_fields & ISO_ROCK_SUF_RE)
|
||||
goto fail;
|
||||
|
||||
/* Test for gaps between extents. Important: Use previous .total_size */
|
||||
extent_lsn = from_733 (p_iso9660_dir->extent);
|
||||
|
@ -831,7 +851,10 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
|
|||
/* Only now update .total_size */
|
||||
p_stat->total_size += from_733(p_iso9660_dir->size);
|
||||
|
||||
p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */
|
||||
#ifdef HAVE_ROCK
|
||||
if (_iso9660_is_rock_ridge_enabled(p_image))
|
||||
p_stat->rr.b3_rock = dunno;
|
||||
#endif
|
||||
p_stat->b_xa = false;
|
||||
|
||||
#ifndef DO_NOT_WANT_COMPATIBILITY
|
||||
|
@ -842,8 +865,7 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
|
|||
#endif /* DO_NOT_WANT_COMPATIBILITY */
|
||||
|
||||
/* Only resolve the full filename when we're not dealing with extent */
|
||||
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
|
||||
{
|
||||
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0) {
|
||||
/* Check if this is the last part of a multiextent file */
|
||||
if (!first_extent) {
|
||||
if (strlen(p_stat->filename) != i_fname ||
|
||||
|
@ -853,11 +875,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
i_rr_fname =
|
||||
|
||||
#ifdef HAVE_ROCK
|
||||
get_rock_ridge_filename(p_iso9660_dir, rr_fname, p_stat);
|
||||
#else
|
||||
0;
|
||||
i_rr_fname = get_rock_ridge_filename(p_iso9660_dir, p_image, rr_fname, p_stat);
|
||||
#endif
|
||||
|
||||
if (i_rr_fname > 0) {
|
||||
|
@ -1024,7 +1044,7 @@ _fs_stat_root (CdIo_t *p_cdio)
|
|||
p_iso9660_dir = &(p_env->pvd.root_directory_record) ;
|
||||
#endif
|
||||
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_cdio,
|
||||
b_xa, p_env->u_joliet_level);
|
||||
return p_stat;
|
||||
}
|
||||
|
@ -1046,7 +1066,7 @@ _ifs_stat_root (iso9660_t *p_iso)
|
|||
#endif
|
||||
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
|
||||
p_iso->b_xa,
|
||||
p_iso, p_iso->b_xa,
|
||||
p_iso->u_joliet_level);
|
||||
return p_stat;
|
||||
}
|
||||
|
@ -1105,8 +1125,8 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
|
|||
/* Do not register remaining extents of ill file */
|
||||
p_iso9660_stat = NULL;
|
||||
} else {
|
||||
p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir,
|
||||
p_iso9660_stat, dunno, p_env->u_joliet_level);
|
||||
p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso9660_stat,
|
||||
(CdIo_t*)p_cdio, dunno, p_env->u_joliet_level);
|
||||
if (NULL == p_iso9660_stat)
|
||||
skip_following_extents = true; /* Start ill file mode */
|
||||
}
|
||||
|
@ -1213,7 +1233,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
|
|||
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
|
||||
continue;
|
||||
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_stat,
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_stat, p_iso,
|
||||
p_iso->b_xa, p_iso->u_joliet_level);
|
||||
|
||||
if (!p_stat) {
|
||||
|
@ -1476,8 +1496,8 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
|
|||
p_iso9660_stat = NULL;
|
||||
} else {
|
||||
p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
|
||||
p_iso9660_stat, dunno,
|
||||
p_env->u_joliet_level);
|
||||
p_iso9660_stat, p_cdio,
|
||||
dunno, p_env->u_joliet_level);
|
||||
if (NULL == p_iso9660_stat)
|
||||
skip_following_extents = true; /* Start ill file mode */
|
||||
}
|
||||
|
@ -1570,10 +1590,13 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
|
|||
} else {
|
||||
p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
|
||||
p_iso9660_stat,
|
||||
p_iso,
|
||||
p_iso->b_xa,
|
||||
p_iso->u_joliet_level);
|
||||
if (NULL == p_iso9660_stat)
|
||||
skip_following_extents = true; /* Start ill file mode */
|
||||
else if (p_iso9660_stat->rr.u_su_fields & ISO_ROCK_SUF_RE)
|
||||
continue; /* Ignore RE entries */
|
||||
}
|
||||
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
|
||||
skip_following_extents = false; /* Ill or not: The file ends now */
|
||||
|
@ -1752,6 +1775,55 @@ iso9660_ifs_find_lsn(iso9660_t *p_iso, lsn_t i_lsn)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ROCK
|
||||
/* Some compilers complain if the prototype is not defined */
|
||||
iso9660_stat_t *
|
||||
_iso9660_dd_find_lsn(void* p_image, lsn_t i_lsn);
|
||||
|
||||
/* Same as above for Rock Ridge deep directory traversing. */
|
||||
iso9660_stat_t *
|
||||
_iso9660_dd_find_lsn(void* p_image, lsn_t i_lsn)
|
||||
{
|
||||
cdio_header_t* p_header = (cdio_header_t*)p_image;
|
||||
char* psz_full_filename = NULL;
|
||||
void* p_image_dd;
|
||||
iso9660_readdir_t* f_readdir;
|
||||
iso9660_stat_t* ret;
|
||||
size_t size;
|
||||
|
||||
switch(p_header->u_type) {
|
||||
case CDIO_HEADER_TYPE_ISO:
|
||||
size = sizeof(iso9660_t);
|
||||
f_readdir = (iso9660_readdir_t*)iso9660_ifs_readdir;
|
||||
break;
|
||||
case CDIO_HEADER_TYPE_CDIO:
|
||||
size = sizeof(CdIo_t);
|
||||
f_readdir = (iso9660_readdir_t*)iso9660_fs_readdir;
|
||||
break;
|
||||
default:
|
||||
cdio_assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Work with a duplicate to allow concurrency. */
|
||||
p_image_dd = calloc(1, size);
|
||||
if (!p_image_dd) {
|
||||
cdio_warn("Memory duplication error");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(p_image_dd, p_image, size);
|
||||
|
||||
/* Disable the deep directory flag so we can process all entries */
|
||||
p_header = (cdio_header_t*)p_image_dd;
|
||||
p_header->u_flags |= CDIO_HEADER_FLAGS_DISABLE_RR_DD;
|
||||
ret = find_lsn_recurse(p_image_dd, f_readdir, "/", i_lsn, &psz_full_filename);
|
||||
if (psz_full_filename != NULL)
|
||||
free(psz_full_filename);
|
||||
free(p_image_dd);
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE ROCK */
|
||||
|
||||
/*!
|
||||
Given a directory pointer, find the filesystem entry that contains
|
||||
lsn and return information about it.
|
||||
|
@ -1860,8 +1932,8 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
|
|||
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
|
||||
continue;
|
||||
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_iso->b_xa,
|
||||
p_iso->u_joliet_level);
|
||||
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_iso,
|
||||
p_iso->b_xa, p_iso->u_joliet_level);
|
||||
have_rr = p_stat->rr.b3_rock;
|
||||
if ( have_rr != yep) {
|
||||
if (strlen(splitpath[0]) == 0)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2020 Pete Batard <pete@akeo.ie>
|
||||
Copyright (C) 2005, 2008, 2010-2011, 2014, 2017 Rocky Bernstein
|
||||
<rocky@gnu.org>
|
||||
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include <cdio/logging.h>
|
||||
#include <cdio/bytesex.h>
|
||||
#include "filemode.h"
|
||||
#include "cdio_private.h"
|
||||
|
||||
#define CDIO_MKDEV(ma,mi) ((ma)<<16 | (mi))
|
||||
|
||||
|
@ -48,6 +50,10 @@ iso_rock_nm_flag_t iso_rock_nm_flag;
|
|||
iso_rock_sl_flag_t iso_rock_sl_flag;
|
||||
iso_rock_tf_flag_t iso_rock_tf_flag;
|
||||
|
||||
/* Used by get_rock_ridge_filename() */
|
||||
extern iso9660_stat_t*
|
||||
_iso9660_dd_find_lsn(void* p_image, lsn_t i_lsn);
|
||||
|
||||
/* Our own realloc routine tailored for the iso9660_stat_t symlink
|
||||
field. I can't figure out how to make realloc() work without
|
||||
valgrind complaint.
|
||||
|
@ -142,12 +148,22 @@ realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t i_grow)
|
|||
} \
|
||||
}
|
||||
|
||||
/* Indicates if we should process deep directory entries */
|
||||
static inline bool
|
||||
is_rr_dd_enabled(void * p_image) {
|
||||
cdio_header_t* p_header = (cdio_header_t*)p_image;
|
||||
if (!p_header)
|
||||
return false;
|
||||
return !(p_header->u_flags & CDIO_HEADER_FLAGS_DISABLE_RR_DD);
|
||||
}
|
||||
|
||||
/*!
|
||||
Get
|
||||
@return length of name field; 0: not found, -1: to be ignored
|
||||
*/
|
||||
int
|
||||
get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
||||
/*in*/ void * p_image,
|
||||
/*out*/ char * psz_name,
|
||||
/*in/out*/ iso9660_stat_t *p_stat)
|
||||
{
|
||||
|
@ -158,7 +174,8 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
int i_namelen = 0;
|
||||
int truncate=0;
|
||||
|
||||
if (!p_stat || nope == p_stat->rr.b3_rock) return 0;
|
||||
if (!p_stat || nope == p_stat->rr.b3_rock)
|
||||
return 0;
|
||||
*psz_name = 0;
|
||||
|
||||
SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
|
||||
|
@ -172,19 +189,21 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
rr = (iso_extension_record_t *) chr;
|
||||
sig = *chr+(*(chr+1) << 8);
|
||||
|
||||
/* We used to check for some vaid values of SIG, specifically
|
||||
/* We used to check for some valid values of SIG, specifically
|
||||
SP, CE, ER, RR, PX, PN, SL, NM, CL, PL, TF, and ZF.
|
||||
However there are various extensions to this set. So we
|
||||
skip checking now.
|
||||
*/
|
||||
|
||||
if (rr->len == 0) goto out; /* Something got screwed up here */
|
||||
if (rr->len == 0)
|
||||
goto out; /* Something got screwed up here */
|
||||
chr += rr->len;
|
||||
len -= rr->len;
|
||||
|
||||
switch(sig){
|
||||
switch(sig) {
|
||||
case SIG('S','P'):
|
||||
CHECK_SP(goto out);
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_SP;
|
||||
break;
|
||||
case SIG('C','E'):
|
||||
{
|
||||
|
@ -195,19 +214,21 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
break;
|
||||
}
|
||||
CHECK_CE;
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_CE;
|
||||
break;
|
||||
case SIG('E','R'):
|
||||
p_stat->rr.b3_rock = yep;
|
||||
cdio_debug("ISO 9660 Extensions: ");
|
||||
{
|
||||
int p;
|
||||
for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]);
|
||||
for (p=0; p < rr->u.ER.len_id; p++)
|
||||
cdio_debug("%c", rr->u.ER.data[p]);
|
||||
}
|
||||
break;
|
||||
case SIG('N','M'):
|
||||
/* Alternate name */
|
||||
p_stat->rr.b3_rock = yep;
|
||||
if (truncate) break;
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_NM;
|
||||
if (truncate)
|
||||
break;
|
||||
if (rr->u.NM.flags & ISO_ROCK_NM_PARENT) {
|
||||
i_namelen = sizeof("..");
|
||||
strncat(psz_name, "..", i_namelen);
|
||||
|
@ -235,7 +256,7 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks);
|
||||
p_stat->rr.st_uid = from_733(rr->u.PX.st_uid);
|
||||
p_stat->rr.st_gid = from_733(rr->u.PX.st_gid);
|
||||
p_stat->rr.b3_rock = yep;
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_PX;
|
||||
break;
|
||||
case SIG('S','L'):
|
||||
{
|
||||
|
@ -246,6 +267,7 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
slen = rr->len - 5;
|
||||
p_sl = &rr->u.SL.link;
|
||||
p_stat->rr.i_symlink = symlink_len;
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_SL;
|
||||
while (slen > 1){
|
||||
rootflag = 0;
|
||||
switch(p_sl->flags &~1){
|
||||
|
@ -294,9 +316,6 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
realloc_symlink(p_stat, 1);
|
||||
p_stat->rr.psz_symlink[symlink_len]='\0';
|
||||
break;
|
||||
case SIG('R','E'):
|
||||
free(buffer);
|
||||
return -1;
|
||||
case SIG('T','F'):
|
||||
/* Time stamp(s) for a file */
|
||||
{
|
||||
|
@ -308,217 +327,56 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
|
|||
add_time(ISO_ROCK_TF_BACKUP, backup);
|
||||
add_time(ISO_ROCK_TF_EXPIRATION, expiration);
|
||||
add_time(ISO_ROCK_TF_EFFECTIVE, effective);
|
||||
p_stat->rr.b3_rock = yep;
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_TF;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
return i_namelen; /* If 0, this file did not have a NM field */
|
||||
out:
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir,
|
||||
iso9660_stat_t *p_stat, int regard_xa)
|
||||
{
|
||||
int len;
|
||||
unsigned char * chr;
|
||||
int symlink_len = 0;
|
||||
CONTINUE_DECLS;
|
||||
|
||||
if (nope == p_stat->rr.b3_rock) return 0;
|
||||
|
||||
SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len);
|
||||
if (regard_xa)
|
||||
{
|
||||
chr+=14;
|
||||
len-=14;
|
||||
if (len<0) len=0;
|
||||
}
|
||||
|
||||
/* repeat:*/
|
||||
{
|
||||
int sig;
|
||||
iso_extension_record_t * rr;
|
||||
int rootflag;
|
||||
|
||||
while (len > 1){ /* There may be one byte for padding somewhere */
|
||||
rr = (iso_extension_record_t *) chr;
|
||||
if (rr->len == 0) goto out; /* Something got screwed up here */
|
||||
sig = from_721(*chr);
|
||||
chr += rr->len;
|
||||
len -= rr->len;
|
||||
|
||||
switch(sig){
|
||||
case SIG('S','P'):
|
||||
CHECK_SP(goto out);
|
||||
break;
|
||||
case SIG('C','E'):
|
||||
CHECK_CE;
|
||||
break;
|
||||
case SIG('E','R'):
|
||||
p_stat->rr.b3_rock = yep;
|
||||
cdio_debug("ISO 9660 Extensions: ");
|
||||
{ int p;
|
||||
for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]);
|
||||
}
|
||||
break;
|
||||
case SIG('P','X'):
|
||||
p_stat->rr.st_mode = from_733(rr->u.PX.st_mode);
|
||||
p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks);
|
||||
p_stat->rr.st_uid = from_733(rr->u.PX.st_uid);
|
||||
p_stat->rr.st_gid = from_733(rr->u.PX.st_gid);
|
||||
break;
|
||||
case SIG('P','N'):
|
||||
/* Device major,minor number */
|
||||
{ int32_t high, low;
|
||||
high = from_733(rr->u.PN.dev_high);
|
||||
low = from_733(rr->u.PN.dev_low);
|
||||
/*
|
||||
* The Rock Ridge standard specifies that if sizeof(dev_t) <= 4,
|
||||
* then the high field is unused, and the device number is completely
|
||||
* stored in the low field. Some writers may ignore this subtlety,
|
||||
* and as a result we test to see if the entire device number is
|
||||
* stored in the low field, and use that.
|
||||
*/
|
||||
if((low & ~0xff) && high == 0) {
|
||||
p_stat->rr.i_rdev = CDIO_MKDEV(low >> 8, low & 0xff);
|
||||
} else {
|
||||
p_stat->rr.i_rdev = CDIO_MKDEV(high, low);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIG('T','F'):
|
||||
/* Time stamp(s) for a file */
|
||||
{
|
||||
int cnt = 0;
|
||||
add_time(ISO_ROCK_TF_CREATE, create);
|
||||
add_time(ISO_ROCK_TF_MODIFY, modify);
|
||||
add_time(ISO_ROCK_TF_ACCESS, access);
|
||||
add_time(ISO_ROCK_TF_ATTRIBUTES, attributes);
|
||||
add_time(ISO_ROCK_TF_BACKUP, backup);
|
||||
add_time(ISO_ROCK_TF_EXPIRATION, expiration);
|
||||
add_time(ISO_ROCK_TF_EFFECTIVE, effective);
|
||||
p_stat->rr.b3_rock = yep;
|
||||
break;
|
||||
}
|
||||
case SIG('S','L'):
|
||||
{
|
||||
/* Symbolic link */
|
||||
uint8_t slen;
|
||||
iso_rock_sl_part_t * p_sl;
|
||||
iso_rock_sl_part_t * p_oldsl;
|
||||
slen = rr->len - 5;
|
||||
p_sl = &rr->u.SL.link;
|
||||
p_stat->rr.i_symlink = symlink_len;
|
||||
while (slen > 1){
|
||||
rootflag = 0;
|
||||
switch(p_sl->flags &~1){
|
||||
case 0:
|
||||
realloc_symlink(p_stat, p_sl->len);
|
||||
if (p_sl->len)
|
||||
memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
|
||||
p_sl->text, p_sl->len);
|
||||
p_stat->rr.i_symlink += p_sl->len;
|
||||
break;
|
||||
case 4:
|
||||
realloc_symlink(p_stat, 1);
|
||||
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
|
||||
/* continue into next case. */
|
||||
case 2:
|
||||
realloc_symlink(p_stat, 1);
|
||||
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.';
|
||||
break;
|
||||
case 8:
|
||||
rootflag = 1;
|
||||
realloc_symlink(p_stat, 1);
|
||||
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
|
||||
p_stat->rr.i_symlink++;
|
||||
break;
|
||||
default:
|
||||
cdio_warn("Symlink component flag not implemented");
|
||||
}
|
||||
slen -= p_sl->len + 2;
|
||||
p_oldsl = p_sl;
|
||||
p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2);
|
||||
|
||||
if (slen < 2) {
|
||||
if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0))
|
||||
p_stat->rr.i_symlink += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this component record isn't continued, then append a '/'.
|
||||
*/
|
||||
if (!rootflag && (p_oldsl->flags & 1) == 0) {
|
||||
realloc_symlink(p_stat, 1);
|
||||
p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
symlink_len = p_stat->rr.i_symlink;
|
||||
realloc_symlink(p_stat, 1);
|
||||
p_stat->rr.psz_symlink[symlink_len]='\0';
|
||||
break;
|
||||
case SIG('R','E'):
|
||||
cdio_warn("Attempt to read p_stat for relocated directory");
|
||||
goto out;
|
||||
#ifdef FINISHED
|
||||
case SIG('C','L'):
|
||||
/* Child Link for a deep directory */
|
||||
if (!is_rr_dd_enabled(p_image))
|
||||
break;
|
||||
{
|
||||
iso9660_stat_t * reloc;
|
||||
ISOFS_I(p_stat)->i_first_extent = from_733(rr->u.CL.location);
|
||||
reloc = isofs_iget(p_stat->rr.i_sb, p_stat->rr.i_first_extent, 0);
|
||||
if (!reloc)
|
||||
goto out;
|
||||
p_stat->rr.st_mode = reloc->st_mode;
|
||||
p_stat->rr.st_nlinks = reloc->st_nlinks;
|
||||
p_stat->rr.st_uid = reloc->st_uid;
|
||||
p_stat->rr.st_gid = reloc->st_gid;
|
||||
p_stat->rr.i_rdev = reloc->i_rdev;
|
||||
p_stat->rr.i_symlink = reloc->i_symlink;
|
||||
p_stat->rr.i_blocks = reloc->i_blocks;
|
||||
p_stat->rr.i_atime = reloc->i_atime;
|
||||
p_stat->rr.i_ctime = reloc->i_ctime;
|
||||
p_stat->rr.i_mtime = reloc->i_mtime;
|
||||
iput(reloc);
|
||||
iso9660_stat_t* target = NULL;
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_CL;
|
||||
target = _iso9660_dd_find_lsn(p_image, from_733(rr->u.PL.location));
|
||||
if (!target) {
|
||||
cdio_warn("Could not get Rock Ridge deep directory child");
|
||||
break;
|
||||
}
|
||||
memcpy(p_stat, target, sizeof(iso9660_stat_t));
|
||||
/* Prevent the symlink from being freed on the duplicated struct */
|
||||
target->rr.psz_symlink = NULL;
|
||||
iso9660_stat_free(target);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SIG('P','L'):
|
||||
/* Parent link of a deep directory */
|
||||
if (is_rr_dd_enabled(p_image))
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_PL;
|
||||
break;
|
||||
case SIG('R','E'):
|
||||
/* Relocated entry for a deep directory */
|
||||
if (is_rr_dd_enabled(p_image))
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_RE;
|
||||
break;
|
||||
case SIG('S','F'):
|
||||
/* Sparse File */
|
||||
p_stat->rr.u_su_fields |= ISO_ROCK_SUF_SF;
|
||||
cdio_warn("Rock Ridge Sparse File detected");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
free(buffer);
|
||||
if (p_stat->rr.u_su_fields & ISO_ROCK_SUF_FORMAL)
|
||||
p_stat->rr.b3_rock = yep;
|
||||
return i_namelen; /* If 0, this file did not have a NM field */
|
||||
out:
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
parse_rock_ridge_stat(iso9660_dir_t *p_iso9660_dir,
|
||||
/*out*/ iso9660_stat_t *p_stat)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!p_stat) return 0;
|
||||
|
||||
result = parse_rock_ridge_stat_internal(p_iso9660_dir, p_stat, 0);
|
||||
/* if Rock-Ridge flag was reset and we didn't look for attributes
|
||||
* behind eventual XA attributes, have a look there */
|
||||
if (0xFF == p_stat->rr.s_rock_offset && nope != p_stat->rr.b3_rock) {
|
||||
result = parse_rock_ridge_stat_internal(p_iso9660_dir, p_stat, 14);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define BUF_COUNT 16
|
||||
#define BUF_SIZE sizeof("drwxrwxrwx")
|
||||
|
||||
|
|
|
@ -1052,6 +1052,7 @@ static void DisplayISOProps(void)
|
|||
|
||||
PRINT_ISO_PROP(img_report.has_4GB_file, " Has a >4GB file");
|
||||
PRINT_ISO_PROP(img_report.has_long_filename, " Has a >64 chars filename");
|
||||
PRINT_ISO_PROP(img_report.has_deep_directories, " Has a Rock Ridge deep directory");
|
||||
PRINT_ISO_PROP(HAS_SYSLINUX(img_report), " Uses: Syslinux/Isolinux v%s", img_report.sl_version_str);
|
||||
if (HAS_SYSLINUX(img_report) && (SL_MAJOR(img_report.sl_version) < 5)) {
|
||||
for (i = 0; i<NB_OLD_C32; i++) {
|
||||
|
|
|
@ -338,6 +338,7 @@ typedef struct {
|
|||
uint8_t has_symlinks;
|
||||
BOOLEAN has_4GB_file;
|
||||
BOOLEAN has_long_filename;
|
||||
BOOLEAN has_deep_directories;
|
||||
BOOLEAN has_bootmgr;
|
||||
BOOLEAN has_bootmgr_efi;
|
||||
BOOLEAN has_autorun;
|
||||
|
|
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 3.11.1658"
|
||||
CAPTION "Rufus 3.11.1659"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -395,8 +395,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,11,1658,0
|
||||
PRODUCTVERSION 3,11,1658,0
|
||||
FILEVERSION 3,11,1659,0
|
||||
PRODUCTVERSION 3,11,1659,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -414,13 +414,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "3.11.1658"
|
||||
VALUE "FileVersion", "3.11.1659"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
VALUE "OriginalFilename", "rufus-3.11.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "3.11.1658"
|
||||
VALUE "ProductVersion", "3.11.1659"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Reference in a new issue