1
1
Fork 0
mirror of https://github.com/pbatard/rufus.git synced 2024-08-14 23:57:05 +00:00

[iso] add support for ISO9660 multiextent files

* Closes #1007
This commit is contained in:
Pete Batard 2017-09-14 17:30:41 +01:00
parent 14d2a629c9
commit 44c9cb0b82
5 changed files with 177 additions and 125 deletions

View file

@ -498,7 +498,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
CdioListNode_t* p_entnode; CdioListNode_t* p_entnode;
iso9660_stat_t *p_statbuf; iso9660_stat_t *p_statbuf;
CdioList_t* p_entlist; CdioList_t* p_entlist;
size_t i; size_t i, j;
lsn_t lsn; lsn_t lsn;
int64_t i_file_length; int64_t i_file_length;
@ -552,7 +552,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
if (iso_extract_files(p_iso, psz_iso_name)) if (iso_extract_files(p_iso, psz_iso_name))
goto out; goto out;
} else { } else {
i_file_length = p_statbuf->size; i_file_length = p_statbuf->total_size;
if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) { if (check_iso_props(psz_path, i_file_length, psz_basename, psz_fullpath, &props)) {
continue; continue;
} }
@ -586,24 +586,27 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
uprintf(stupid_antivirus); uprintf(stupid_antivirus);
else else
goto out; goto out;
} else for (i=0; i_file_length>0; i++) { } else for (j=0; j<p_statbuf->extents; j++) {
if (FormatStatus) goto out; i_file_length = p_statbuf->size[j];
memset(buf, 0, ISO_BLOCKSIZE); for (i=0; i_file_length>0; i++) {
lsn = p_statbuf->lsn + (lsn_t)i; if (FormatStatus) goto out;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { memset(buf, 0, ISO_BLOCKSIZE);
uprintf(" Error reading ISO9660 file %s at LSN %lu", lsn = p_statbuf->lsn[j] + (lsn_t)i;
psz_iso_name, (long unsigned int)lsn); if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
goto out; uprintf(" Error reading ISO9660 file %s at LSN %lu",
psz_iso_name, (long unsigned int)lsn);
goto out;
}
buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r) {
uprintf(" Error writing file: %s", WindowsErrorString());
goto out;
}
i_file_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
} }
buf_size = (DWORD)MIN(i_file_length, ISO_BLOCKSIZE);
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r) {
uprintf(" Error writing file: %s", WindowsErrorString());
goto out;
}
i_file_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
} }
if (preserve_timestamps) { if (preserve_timestamps) {
LPFILETIME ft = to_filetime(mktime(&p_statbuf->tm)); LPFILETIME ft = to_filetime(mktime(&p_statbuf->tm));
@ -944,7 +947,7 @@ out:
int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes) int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_file, DWORD attributes)
{ {
size_t i; size_t i, j;
ssize_t read_size; ssize_t read_size;
int64_t file_length, r = 0; int64_t file_length, r = 0;
char buf[UDF_BLOCKSIZE]; char buf[UDF_BLOCKSIZE];
@ -1009,21 +1012,23 @@ try_iso:
goto out; goto out;
} }
file_length = p_statbuf->size; for (j = 0; j < p_statbuf->extents; j++) {
for (i = 0; file_length > 0; i++) { file_length = p_statbuf->size[j];
memset(buf, 0, ISO_BLOCKSIZE); for (i = 0; file_length > 0; i++) {
lsn = p_statbuf->lsn + (lsn_t)i; memset(buf, 0, ISO_BLOCKSIZE);
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { lsn = p_statbuf->lsn[j] + (lsn_t)i;
uprintf(" Error reading ISO9660 file %s at LSN %lu", iso_file, (long unsigned int)lsn); if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
goto out; uprintf(" Error reading ISO9660 file %s at LSN %lu", iso_file, (long unsigned int)lsn);
goto out;
}
buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE);
if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) {
uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString());
goto out;
}
file_length -= ISO_BLOCKSIZE;
r += ISO_BLOCKSIZE;
} }
buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE);
if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) {
uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString());
goto out;
}
file_length -= ISO_BLOCKSIZE;
r += ISO_BLOCKSIZE;
} }
out: out:
@ -1092,8 +1097,8 @@ try_iso:
uprintf("Could not get ISO-9660 file information for file %s", wim_path); uprintf("Could not get ISO-9660 file information for file %s", wim_path);
goto out; goto out;
} }
if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) { if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn[0], 1) != ISO_BLOCKSIZE) {
uprintf("Error reading ISO-9660 file %s at LSN %lu", wim_path, (long unsigned int)p_statbuf->lsn); uprintf("Error reading ISO-9660 file %s at LSN %d", wim_path, p_statbuf->lsn[0]);
goto out; goto out;
} }
r = wim_header[3]; r = wim_header[3];
@ -1190,7 +1195,7 @@ BOOL ExtractEfiImgFiles(const char* dir)
if (p_private == NULL) if (p_private == NULL)
goto out; goto out;
p_private->p_iso = p_iso; p_private->p_iso = p_iso;
p_private->lsn = p_statbuf->lsn; p_private->lsn = p_statbuf->lsn[0]; // Image should be small enough not to use multiextents
p_private->sec_start = 0; p_private->sec_start = 0;
// Populate our intial buffer // Populate our intial buffer
if (iso9660_iso_seek_read(p_private->p_iso, p_private->buf, p_private->lsn, ISO_NB_BLOCKS) != ISO_NB_BLOCKS * ISO_BLOCKSIZE) { if (iso9660_iso_seek_read(p_private->p_iso, p_private->buf, p_private->lsn, ISO_NB_BLOCKS) != ISO_NB_BLOCKS * ISO_BLOCKSIZE) {

View file

@ -156,6 +156,9 @@ extern enum iso_vd_enum_s {
/*! \brief Maximum number of characters in a volume-set id. */ /*! \brief Maximum number of characters in a volume-set id. */
#define ISO_MAX_VOLUMESET_ID 128 #define ISO_MAX_VOLUMESET_ID 128
/*! \brief Maximum number of multi file extent licdio supports. */
#define ISO_MAX_MULTIEXTENT 8
/*! String inside frame which identifies an ISO 9660 filesystem. This /*! String inside frame which identifies an ISO 9660 filesystem. This
string is the "id" field of an iso9660_pvd_t or an iso9660_svd_t. string is the "id" field of an iso9660_pvd_t or an iso9660_svd_t.
*/ */
@ -517,17 +520,19 @@ PRAGMA_END_PACKED
*/ */
struct iso9660_stat_s { /* big endian!! */ struct iso9660_stat_s { /* big endian!! */
iso_rock_statbuf_t rr; /**< Rock Ridge-specific fields */ iso_rock_statbuf_t rr; /**< Rock Ridge-specific fields */
struct tm tm; /**< time on entry - FIXME merge with struct tm tm; /**< time on entry - FIXME merge with
one of entries above, like ctime? */ one of entries above, like ctime? */
lsn_t lsn; /**< start logical sector number */ uint64_t total_size; /**< total size in bytes */
uint32_t size; /**< total size in bytes */ uint8_t extents; /**< number of multiextents */
uint32_t secsize; /**< number of sectors allocated */ lsn_t lsn[ISO_MAX_MULTIEXTENT]; /**< start logical sector number for each extent */
uint32_t size[ISO_MAX_MULTIEXTENT]; /**< size of each extent */
uint32_t secsize[ISO_MAX_MULTIEXTENT]; /**< number of sectors allocated for each extent*/
iso9660_xa_t xa; /**< XA attributes */ iso9660_xa_t xa; /**< XA attributes */
enum { _STAT_FILE = 1, _STAT_DIR = 2 } type; enum { _STAT_FILE = 1, _STAT_DIR = 2 } type;
bool b_xa; bool b_xa;
char filename[EMPTY_ARRAY_SIZE]; /**< filename */ char filename[EMPTY_ARRAY_SIZE]; /**< filename */
}; };
/** A mask used in iso9660_ifs_read_vd which allows what kinds /** A mask used in iso9660_ifs_read_vd which allows what kinds

View file

@ -709,14 +709,17 @@ iso9660_iso_seek_read (const iso9660_t *p_iso, void *ptr, lsn_t start,
static iso9660_stat_t * static iso9660_stat_t *
_iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa, _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
uint8_t u_joliet_level) iso9660_stat_t *last_p_stat,
bool_3way_t b_xa, uint8_t u_joliet_level)
{ {
uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir); uint8_t dir_len= iso9660_get_dir_len(p_iso9660_dir);
iso711_t i_fname; iso711_t i_fname;
unsigned int stat_len; unsigned int stat_len;
iso9660_stat_t *p_stat; iso9660_stat_t *p_stat = last_p_stat;
bool err; bool err;
char rr_fname[256] = "";
int i_rr_fname;
if (!dir_len) return NULL; if (!dir_len) return NULL;
@ -725,7 +728,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa,
/* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */ /* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */
stat_len = sizeof(iso9660_stat_t)+i_fname+2; stat_len = sizeof(iso9660_stat_t)+i_fname+2;
p_stat = calloc(1, stat_len); /* Reuse multiextent p_stat if not NULL */
if (!p_stat)
p_stat = calloc(1, stat_len);
if (!p_stat) if (!p_stat)
{ {
cdio_warn("Couldn't calloc(1, %d)", stat_len); cdio_warn("Couldn't calloc(1, %d)", stat_len);
@ -733,24 +738,33 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa,
} }
p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY) p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY)
? _STAT_DIR : _STAT_FILE; ? _STAT_DIR : _STAT_FILE;
p_stat->lsn = from_733_with_err (p_iso9660_dir->extent, &err); p_stat->lsn[p_stat->extents] = from_733_with_err (p_iso9660_dir->extent, &err);
if (err) { if (err) {
free(p_stat); free(p_stat);
return NULL; return NULL;
} }
p_stat->size = from_733_with_err (p_iso9660_dir->size, &err); p_stat->size[p_stat->extents] = from_733_with_err (p_iso9660_dir->size, &err);
p_stat->total_size += p_stat->size[p_stat->extents];
if (err) { if (err) {
free(p_stat); free(p_stat);
return NULL; return NULL;
} }
p_stat->secsize = _cdio_len2blocks (p_stat->size, ISO_BLOCKSIZE); p_stat->secsize[p_stat->extents] = _cdio_len2blocks (p_stat->size[p_stat->extents], ISO_BLOCKSIZE);
p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */ p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */
p_stat->b_xa = false; p_stat->b_xa = false;
/* Only resolve the full filename when we're not dealing with extent */
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
{ {
char rr_fname[256] = ""; /* Check if this is the last part of a multiextent file */
if (p_stat->extents != 0) {
int i_rr_fname = if (strcmp(p_stat->filename, &p_iso9660_dir->filename.str[1]) != 0) {
cdio_warn("Warning: Non consecutive multiextent file parts for '%s'", p_stat->filename);
free(p_stat);
return NULL;
}
}
i_rr_fname =
#ifdef HAVE_ROCK #ifdef HAVE_ROCK
get_rock_ridge_filename(p_iso9660_dir, rr_fname, p_stat); get_rock_ridge_filename(p_iso9660_dir, rr_fname, p_stat);
#else #else
@ -797,13 +811,16 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa,
strncpy (p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname); strncpy (p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
} }
} }
} else {
/* Use the plain ISO-9660 name when dealing with a multiextent file part */
strncpy(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
} }
p_stat->extents++;
if (p_iso9660_dir->file_flags & ISO_MULTIEXTENT) if (p_stat->extents > ISO_MAX_MULTIEXTENT) {
{ cdio_warn("Warning: Too many multiextent file parts for '%s'", p_stat->filename);
cdio_warn("Can't handle multi-extent file '%s' - Data will be truncated!", p_stat->filename); free(p_stat->rr.psz_symlink);
free(p_stat); free(p_stat);
return NULL; return NULL;
} }
iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm)); iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm));
@ -927,8 +944,8 @@ _fs_stat_root (CdIo_t *p_cdio)
p_iso9660_dir = &(p_env->pvd.root_directory_record) ; p_iso9660_dir = &(p_env->pvd.root_directory_record) ;
#endif #endif
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, b_xa, p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
p_env->u_joliet_level); b_xa, p_env->u_joliet_level);
return p_stat; return p_stat;
} }
@ -948,7 +965,8 @@ _ifs_stat_root (iso9660_t *p_iso)
p_iso9660_dir = &(p_iso->pvd.root_directory_record) ; p_iso9660_dir = &(p_iso->pvd.root_directory_record) ;
#endif #endif
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso->b_xa, p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
p_iso->b_xa,
p_iso->u_joliet_level); p_iso->u_joliet_level);
return p_stat; return p_stat;
} }
@ -980,18 +998,18 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
cdio_assert (_root->type == _STAT_DIR); cdio_assert (_root->type == _STAT_DIR);
_dirbuf = calloc(1, _root->secsize * ISO_BLOCKSIZE); _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", _root->secsize * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE);
return NULL; return NULL;
} }
if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn, ISO_BLOCKSIZE, if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn[0], ISO_BLOCKSIZE,
_root->secsize)) _root->secsize[0]))
return NULL; return NULL;
while (offset < (_root->secsize * ISO_BLOCKSIZE)) while (offset < (_root->secsize[0] * ISO_BLOCKSIZE))
{ {
iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
iso9660_stat_t *p_iso9660_stat; iso9660_stat_t *p_iso9660_stat;
@ -1003,8 +1021,8 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
continue; continue;
} }
p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, dunno, p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL,
p_env->u_joliet_level); dunno, p_env->u_joliet_level);
cmp = strcmp(splitpath[0], p_iso9660_stat->filename); cmp = strcmp(splitpath[0], p_iso9660_stat->filename);
@ -1043,7 +1061,7 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
offset += iso9660_get_dir_len(p_iso9660_dir); offset += iso9660_get_dir_len(p_iso9660_dir);
} }
cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE)); cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE));
/* not found */ /* not found */
free (_dirbuf); free (_dirbuf);
@ -1054,13 +1072,14 @@ static iso9660_stat_t *
_fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
char **splitpath) char **splitpath)
{ {
unsigned offset = 0; unsigned offset;
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
int ret; int ret;
iso9660_stat_t *p_stat = NULL;
iso9660_dir_t *p_iso9660_dir = NULL;
if (!splitpath[0]) if (!splitpath[0])
{ {
iso9660_stat_t *p_stat;
unsigned int len=sizeof(iso9660_stat_t) + strlen(_root->filename)+1; unsigned int len=sizeof(iso9660_stat_t) + strlen(_root->filename)+1;
p_stat = calloc(1, len); p_stat = calloc(1, len);
cdio_assert (p_stat != NULL); cdio_assert (p_stat != NULL);
@ -1077,20 +1096,20 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
cdio_assert (_root->type == _STAT_DIR); cdio_assert (_root->type == _STAT_DIR);
_dirbuf = calloc(1, _root->secsize * ISO_BLOCKSIZE); _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", _root->secsize * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE);
return NULL; return NULL;
} }
ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, _root->secsize); ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]);
if (ret!=ISO_BLOCKSIZE*_root->secsize) return NULL; if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) return NULL;
while (offset < (_root->secsize * ISO_BLOCKSIZE)) for (offset = 0; offset < (_root->secsize[0] * ISO_BLOCKSIZE);
offset += iso9660_get_dir_len(p_iso9660_dir))
{ {
iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; p_iso9660_dir = (void *) &_dirbuf[offset];
iso9660_stat_t *p_stat;
int cmp; int cmp;
if (!iso9660_get_dir_len(p_iso9660_dir)) if (!iso9660_get_dir_len(p_iso9660_dir))
@ -1099,8 +1118,8 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
continue; continue;
} }
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso->b_xa, p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_stat,
p_iso->u_joliet_level); p_iso->b_xa, p_iso->u_joliet_level);
if (!p_stat) { if (!p_stat) {
cdio_warn("Bad directory information for %s", splitpath[0]); cdio_warn("Bad directory information for %s", splitpath[0]);
@ -1108,6 +1127,10 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
return NULL; return NULL;
} }
/* If we have multiextent file parts, loop until the last one */
if (p_iso9660_dir->file_flags & ISO_MULTIEXTENT)
continue;
cmp = strcmp(splitpath[0], p_stat->filename); cmp = strcmp(splitpath[0], p_stat->filename);
if ( 0 != cmp && 0 == p_iso->u_joliet_level if ( 0 != cmp && 0 == p_iso->u_joliet_level
@ -1141,11 +1164,10 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
free(p_stat->rr.psz_symlink); free(p_stat->rr.psz_symlink);
free(p_stat); free(p_stat);
p_stat = NULL;
offset += iso9660_get_dir_len(p_iso9660_dir);
} }
cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE)); cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE));
/* not found */ /* not found */
free (_dirbuf); free (_dirbuf);
@ -1268,6 +1290,8 @@ CdioList_t *
iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2) iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
{ {
generic_img_private_t *p_env; generic_img_private_t *p_env;
iso9660_dir_t *p_iso9660_dir;
iso9660_stat_t *p_iso9660_stat = NULL;
iso9660_stat_t *p_stat; iso9660_stat_t *p_stat;
if (!p_cdio) return NULL; if (!p_cdio) return NULL;
@ -1289,24 +1313,23 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
CdioList_t *retval = _cdio_list_new (); CdioList_t *retval = _cdio_list_new ();
_dirbuf = calloc(1, p_stat->secsize * ISO_BLOCKSIZE); _dirbuf = calloc(1, p_stat->secsize[0] * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", p_stat->secsize * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", p_stat->secsize[0] * ISO_BLOCKSIZE);
_cdio_list_free (retval, true); _cdio_list_free (retval, true);
return NULL; return NULL;
} }
if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn, if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn[0],
ISO_BLOCKSIZE, p_stat->secsize)) { ISO_BLOCKSIZE, p_stat->secsize[0])) {
_cdio_list_free (retval, true); _cdio_list_free (retval, true);
return NULL; return NULL;
} }
while (offset < (p_stat->secsize * ISO_BLOCKSIZE)) while (offset < (p_stat->secsize[0] * ISO_BLOCKSIZE))
{ {
iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; p_iso9660_dir = (void *) &_dirbuf[offset];
iso9660_stat_t *p_iso9660_stat;
if (!iso9660_get_dir_len(p_iso9660_dir)) if (!iso9660_get_dir_len(p_iso9660_dir))
{ {
@ -1314,14 +1337,20 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
continue; continue;
} }
p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, dunno, p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
p_iso9660_stat, dunno,
p_env->u_joliet_level); p_env->u_joliet_level);
_cdio_list_append (retval, p_iso9660_stat); if ((p_iso9660_stat) &&
((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0))
{
_cdio_list_append (retval, p_iso9660_stat);
p_iso9660_stat = NULL;
}
offset += iso9660_get_dir_len(p_iso9660_dir); offset += iso9660_get_dir_len(p_iso9660_dir);
} }
cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE)); cdio_assert (offset == (p_stat->secsize[0] * ISO_BLOCKSIZE));
free (_dirbuf); free (_dirbuf);
free (p_stat); free (p_stat);
@ -1336,6 +1365,8 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[], bool b_mode2)
CdioList_t * CdioList_t *
iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
{ {
iso9660_dir_t *p_iso9660_dir;
iso9660_stat_t *p_iso9660_stat = NULL;
iso9660_stat_t *p_stat; iso9660_stat_t *p_stat;
if (!p_iso) return NULL; if (!p_iso) return NULL;
@ -1355,12 +1386,12 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
unsigned offset = 0; unsigned offset = 0;
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
CdioList_t *retval = _cdio_list_new (); CdioList_t *retval = _cdio_list_new ();
const size_t dirbuf_len = p_stat->secsize * ISO_BLOCKSIZE; const size_t dirbuf_len = p_stat->secsize[0] * ISO_BLOCKSIZE;
if (!dirbuf_len) if (!dirbuf_len)
{ {
cdio_warn("Invalid directory buffer sector size %u", p_stat->secsize); cdio_warn("Invalid directory buffer sector size %u", p_stat->secsize[0]);
free(p_stat->rr.psz_symlink); free(p_stat->rr.psz_symlink);
free(p_stat); free(p_stat);
_cdio_list_free (retval, true); _cdio_list_free (retval, true);
@ -1377,7 +1408,7 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
return NULL; return NULL;
} }
ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn, p_stat->secsize); ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn[0], p_stat->secsize[0]);
if (ret != dirbuf_len) { if (ret != dirbuf_len) {
_cdio_list_free (retval, true); _cdio_list_free (retval, true);
free(p_stat->rr.psz_symlink); free(p_stat->rr.psz_symlink);
@ -1388,8 +1419,7 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
while (offset < (dirbuf_len)) while (offset < (dirbuf_len))
{ {
iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; p_iso9660_dir = (void *) &_dirbuf[offset];
iso9660_stat_t *p_iso9660_stat;
if (!iso9660_get_dir_len(p_iso9660_dir)) if (!iso9660_get_dir_len(p_iso9660_dir))
{ {
@ -1397,11 +1427,16 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
continue; continue;
} }
p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, p_iso->b_xa, p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir,
p_iso9660_stat,
p_iso->b_xa,
p_iso->u_joliet_level); p_iso->u_joliet_level);
if ((p_iso9660_stat) &&
if (p_iso9660_stat) ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0))
_cdio_list_append (retval, p_iso9660_stat); {
_cdio_list_append(retval, p_iso9660_stat);
p_iso9660_stat = NULL;
}
offset += iso9660_get_dir_len(p_iso9660_dir); offset += iso9660_get_dir_len(p_iso9660_dir);
} }
@ -1440,6 +1475,7 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
iso9660_stat_t *statbuf = _cdio_list_node_data (entnode); iso9660_stat_t *statbuf = _cdio_list_node_data (entnode);
const char *psz_filename = (char *) statbuf->filename; const char *psz_filename = (char *) statbuf->filename;
unsigned int len = strlen(psz_path) + strlen(psz_filename)+2; unsigned int len = strlen(psz_path) + strlen(psz_filename)+2;
size_t extent;
if (*ppsz_full_filename != NULL) free(*ppsz_full_filename); if (*ppsz_full_filename != NULL) free(*ppsz_full_filename);
*ppsz_full_filename = calloc(1, len); *ppsz_full_filename = calloc(1, len);
@ -1451,19 +1487,20 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
_cdio_list_append (dirlist, strdup(*ppsz_full_filename)); _cdio_list_append (dirlist, strdup(*ppsz_full_filename));
} }
if (statbuf->lsn == lsn) { for (extent = 0; extent < statbuf->extents; extent++) {
const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1; if (statbuf->lsn[extent] == lsn) {
iso9660_stat_t *ret_stat = calloc(1, len2); const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1;
if (!ret_stat) iso9660_stat_t *ret_stat = calloc(1, len2);
{ if (!ret_stat) {
_cdio_list_free (dirlist, true); _cdio_list_free (dirlist, true);
cdio_warn("Couldn't calloc(1, %d)", len2); cdio_warn("Couldn't calloc(1, %d)", len2);
return NULL; return NULL;
} }
memcpy(ret_stat, statbuf, len2); memcpy(ret_stat, statbuf, len2);
_cdio_list_free (entlist, true); _cdio_list_free (entlist, true);
_cdio_list_free (dirlist, true); _cdio_list_free (dirlist, true);
return ret_stat; return ret_stat;
}
} }
} }
@ -1588,17 +1625,17 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
cdio_assert (_root->type == _STAT_DIR); cdio_assert (_root->type == _STAT_DIR);
_dirbuf = calloc(1, _root->secsize * ISO_BLOCKSIZE); _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", _root->secsize * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE);
return dunno; return dunno;
} }
ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, _root->secsize); ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]);
if (ret!=ISO_BLOCKSIZE*_root->secsize) return false; if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) return false;
while (offset < (_root->secsize * ISO_BLOCKSIZE)) while (offset < (_root->secsize[0] * ISO_BLOCKSIZE))
{ {
iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
iso9660_stat_t *p_stat; iso9660_stat_t *p_stat;
@ -1609,7 +1646,7 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
continue; continue;
} }
p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, p_iso->b_xa, p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_iso->b_xa,
p_iso->u_joliet_level); p_iso->u_joliet_level);
have_rr = p_stat->rr.b3_rock; have_rr = p_stat->rr.b3_rock;
if ( have_rr != yep) { if ( have_rr != yep) {
@ -1629,7 +1666,7 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
} }
} }
cdio_assert (offset == (_root->secsize * ISO_BLOCKSIZE)); cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE));
/* not found */ /* not found */
free (_dirbuf); free (_dirbuf);

View file

@ -484,9 +484,14 @@ static void SetFSFromISO(void)
fs_mask |= 1<<fs; fs_mask |= 1<<fs;
} }
// The presence of a 4GB file forces the use of NTFS as default FS
if (img_report.has_4GB_file) {
if (fs_mask & (1 << FS_NTFS)) {
selected_fs = FS_NTFS;
}
// Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type) // Syslinux and EFI have precedence over bootmgr (unless the user selected BIOS as target type)
if ((HAS_SYSLINUX(img_report)) || (HAS_REACTOS(img_report)) || HAS_KOLIBRIOS(img_report) || } else if ((HAS_SYSLINUX(img_report)) || (HAS_REACTOS(img_report)) || HAS_KOLIBRIOS(img_report) ||
(IS_EFI_BOOTABLE(img_report) && (tt == TT_UEFI) && (!img_report.has_4GB_file) && (!windows_to_go))) { (IS_EFI_BOOTABLE(img_report) && (tt == TT_UEFI) && (!windows_to_go))) {
if (fs_mask & (1<<FS_FAT32)) { if (fs_mask & (1<<FS_FAT32)) {
selected_fs = FS_FAT32; selected_fs = FS_FAT32;
} else if ((fs_mask & (1<<FS_FAT16)) && !HAS_KOLIBRIOS(img_report)) { } else if ((fs_mask & (1<<FS_FAT16)) && !HAS_KOLIBRIOS(img_report)) {

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 242, 376 IDD_DIALOG DIALOGEX 12, 12, 242, 376
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 2.17.1198" CAPTION "Rufus 2.17.1199"
FONT 8, "Segoe UI Symbol", 400, 0, 0x0 FONT 8, "Segoe UI Symbol", 400, 0, 0x0
BEGIN BEGIN
LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8
@ -366,8 +366,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,17,1198,0 FILEVERSION 2,17,1199,0
PRODUCTVERSION 2,17,1198,0 PRODUCTVERSION 2,17,1199,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -384,13 +384,13 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "2.17.1198" VALUE "FileVersion", "2.17.1199"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2017 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe" VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "2.17.1198" VALUE "ProductVersion", "2.17.1199"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"