Skip to content

Commit

Permalink
[iso] add support for ISO9660 multiextent files
Browse files Browse the repository at this point in the history
* Closes pbatard#1007
  • Loading branch information
pbatard committed Sep 14, 2017
1 parent 14d2a62 commit 44c9cb0
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 125 deletions.
79 changes: 42 additions & 37 deletions src/iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
CdioListNode_t* p_entnode;
iso9660_stat_t *p_statbuf;
CdioList_t* p_entlist;
size_t i;
size_t i, j;
lsn_t lsn;
int64_t i_file_length;

Expand Down Expand Up @@ -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))
goto out;
} 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)) {
continue;
}
Expand Down Expand Up @@ -586,24 +586,27 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path)
uprintf(stupid_antivirus);
else
goto out;
} else for (i=0; i_file_length>0; i++) {
if (FormatStatus) goto out;
memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
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;
} else for (j=0; j<p_statbuf->extents; j++) {
i_file_length = p_statbuf->size[j];
for (i=0; i_file_length>0; i++) {
if (FormatStatus) goto out;
memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn[j] + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
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);
}
i_file_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgress(OP_DOS, 100.0f*nb_blocks/total_blocks);
}
if (preserve_timestamps) {
LPFILETIME ft = to_filetime(mktime(&p_statbuf->tm));
Expand Down Expand Up @@ -944,7 +947,7 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan)

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;
int64_t file_length, r = 0;
char buf[UDF_BLOCKSIZE];
Expand Down Expand Up @@ -1009,21 +1012,23 @@ int64_t ExtractISOFile(const char* iso, const char* iso_file, const char* dest_f
goto out;
}

file_length = p_statbuf->size;
for (i = 0; file_length > 0; i++) {
memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
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;
for (j = 0; j < p_statbuf->extents; j++) {
file_length = p_statbuf->size[j];
for (i = 0; file_length > 0; i++) {
memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn[j] + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
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;
}
file_length -= ISO_BLOCKSIZE;
r += ISO_BLOCKSIZE;
}

out:
Expand Down Expand Up @@ -1092,8 +1097,8 @@ uint32_t GetInstallWimVersion(const char* iso)
uprintf("Could not get ISO-9660 file information for file %s", wim_path);
goto out;
}
if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) {
uprintf("Error reading ISO-9660 file %s at LSN %lu", wim_path, (long unsigned int)p_statbuf->lsn);
if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn[0], 1) != ISO_BLOCKSIZE) {
uprintf("Error reading ISO-9660 file %s at LSN %d", wim_path, p_statbuf->lsn[0]);
goto out;
}
r = wim_header[3];
Expand Down Expand Up @@ -1190,7 +1195,7 @@ BOOL ExtractEfiImgFiles(const char* dir)
if (p_private == NULL)
goto out;
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;
// 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) {
Expand Down
15 changes: 10 additions & 5 deletions src/libcdio/cdio/iso9660.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ extern enum iso_vd_enum_s {
/*! \brief Maximum number of characters in a volume-set id. */
#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 is the "id" field of an iso9660_pvd_t or an iso9660_svd_t.
*/
Expand Down Expand Up @@ -517,17 +520,19 @@ PRAGMA_END_PACKED
*/
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
one of entries above, like ctime? */
lsn_t lsn; /**< start logical sector number */
uint32_t size; /**< total size in bytes */
uint32_t secsize; /**< number of sectors allocated */
uint64_t total_size; /**< total size in bytes */
uint8_t extents; /**< number of multiextents */
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 */
enum { _STAT_FILE = 1, _STAT_DIR = 2 } type;
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
Expand Down
Loading

0 comments on commit 44c9cb0

Please sign in to comment.