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

[iso] update libcdio to latest

This commit is contained in:
Pete Batard 2020-05-24 21:09:27 +01:00
parent 56e87429d7
commit dcc4463273
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
17 changed files with 518 additions and 427 deletions

View file

@ -36,6 +36,7 @@
#include <virtdisk.h> #include <virtdisk.h>
#include <sys/stat.h> #include <sys/stat.h>
#define DO_NOT_WANT_COMPATIBILITY
#include <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/logging.h> #include <cdio/logging.h>
#include <cdio/iso9660.h> #include <cdio/iso9660.h>
@ -630,9 +631,9 @@ 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;
CdioISO9660FileList_t* p_entlist; CdioISO9660FileList_t* p_entlist;
size_t i, j; size_t i;
lsn_t lsn; lsn_t lsn;
int64_t file_length, extent_length; int64_t file_length;
if ((p_iso == NULL) || (psz_path == NULL)) if ((p_iso == NULL) || (psz_path == NULL))
return 1; return 1;
@ -686,7 +687,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 {
file_length = p_statbuf->size; file_length = p_statbuf->total_size;
if (check_iso_props(psz_path, file_length, psz_basename, psz_fullpath, &props)) { if (check_iso_props(psz_path, file_length, psz_basename, psz_fullpath, &props)) {
continue; continue;
} }
@ -721,30 +722,25 @@ 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 { } else for (i = 0; file_length > 0; i++) {
for (j=0; j<p_statbuf->extents; j++) {
extent_length = p_statbuf->extsize[j];
for (i=0; extent_length>0; i++) {
if (FormatStatus) goto out; if (FormatStatus) goto out;
memset(buf, 0, ISO_BLOCKSIZE); memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn[j] + (lsn_t)i; lsn = p_statbuf->lsn + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) {
uprintf(" Error reading ISO9660 file %s at LSN %lu", uprintf(" Error reading ISO9660 file %s at LSN %lu",
psz_iso_name, (long unsigned int)lsn); psz_iso_name, (long unsigned int)lsn);
goto out; goto out;
} }
buf_size = (DWORD)MIN(extent_length, ISO_BLOCKSIZE); buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE);
ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)); ISO_BLOCKING(r = WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES));
if (!r) { if (!r) {
uprintf(" Error writing file: %s", WindowsErrorString()); uprintf(" Error writing file: %s", WindowsErrorString());
goto out; goto out;
} }
extent_length -= ISO_BLOCKSIZE; file_length -= ISO_BLOCKSIZE;
if (nb_blocks++ % PROGRESS_THRESHOLD == 0) if (nb_blocks++ % PROGRESS_THRESHOLD == 0)
UpdateProgressWithInfo(OP_FILE_COPY, MSG_231, nb_blocks, total_blocks); UpdateProgressWithInfo(OP_FILE_COPY, MSG_231, 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));
if (!SetFileTime(file_handle, ft, ft, ft)) if (!SetFileTime(file_handle, ft, ft, ft))
@ -1091,9 +1087,9 @@ 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, j; size_t i;
ssize_t read_size; ssize_t read_size;
int64_t file_length, extent_length, r = 0; int64_t file_length, r = 0;
char buf[UDF_BLOCKSIZE]; char buf[UDF_BLOCKSIZE];
DWORD buf_size, wr_size; DWORD buf_size, wr_size;
iso9660_t* p_iso = NULL; iso9660_t* p_iso = NULL;
@ -1156,24 +1152,22 @@ try_iso:
goto out; goto out;
} }
for (j = 0; j < p_statbuf->extents; j++) { file_length = p_statbuf->total_size;
extent_length = p_statbuf->extsize[j]; for (i = 0; file_length > 0; i++) {
for (i = 0; extent_length > 0; i++) {
memset(buf, 0, ISO_BLOCKSIZE); memset(buf, 0, ISO_BLOCKSIZE);
lsn = p_statbuf->lsn[j] + (lsn_t)i; lsn = p_statbuf->lsn + (lsn_t)i;
if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { 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); uprintf(" Error reading ISO9660 file %s at LSN %lu", iso_file, (long unsigned int)lsn);
goto out; goto out;
} }
buf_size = (DWORD)MIN(extent_length, ISO_BLOCKSIZE); buf_size = (DWORD)MIN(file_length, ISO_BLOCKSIZE);
if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) { if (!WriteFileWithRetry(file_handle, buf, buf_size, &wr_size, WRITE_RETRIES)) {
uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString()); uprintf(" Error writing file %s: %s", dest_file, WindowsErrorString());
goto out; goto out;
} }
extent_length -= ISO_BLOCKSIZE; file_length -= ISO_BLOCKSIZE;
r += ISO_BLOCKSIZE; r += ISO_BLOCKSIZE;
} }
}
out: out:
safe_closehandle(file_handle); safe_closehandle(file_handle);
@ -1241,8 +1235,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[0], 1) != ISO_BLOCKSIZE) { if (iso9660_iso_seek_read(p_iso, buf, p_statbuf->lsn, 1) != ISO_BLOCKSIZE) {
uprintf("Error reading ISO-9660 file %s at LSN %d", wim_path, p_statbuf->lsn[0]); uprintf("Error reading ISO-9660 file %s at LSN %d", wim_path, p_statbuf->lsn);
goto out; goto out;
} }
r = wim_header[3]; r = wim_header[3];
@ -1332,7 +1326,7 @@ BOOL HasEfiImgBootLoaders(void)
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[0]; // Image should be small enough not to use multiextents p_private->lsn = p_statbuf->lsn;
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) {
@ -1424,7 +1418,7 @@ BOOL DumpFatDir(const char* path, int32_t cluster)
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[0]; // Image should be small enough not to use multiextents p_private->lsn = p_statbuf->lsn;
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

@ -1,5 +1,5 @@
/* -*- c -*- /* -*- c -*-
Copyright (C) 2005, 2007, 2008 Rocky Bernstein <rocky@gnu.org> Copyright (C) 2005, 2007, 2008, 2019 Rocky Bernstein <rocky@gnu.org>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -65,8 +65,8 @@ extern "C" {
@param p_cdio the CD object to be acted upon. @param p_cdio the CD object to be acted upon.
@param p_volume place to put the list of volume outputs levels @param p_volume place to put the list of volume outputs levels
p_volume can be NULL in which case we return only whether the driver \p p_volume can be \p NULL in which case we return only whether
has the ability to get the volume or not. the driver has the ability to get the volume or not.
*/ */
driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/ driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/

View file

@ -1,5 +1,6 @@
/* /*
Copyright (C) 2004, 2005, 2008, 2012 Rocky Bernstein <rocky@gnu.org> Copyright (C) 2018 Thomas Schmitt
Copyright (C) 2004, 2005, 2008, 2012, 2019 Rocky Bernstein <rocky@gnu.org>
adapted from cuetools adapted from cuetools
Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm> Copyright (C) 2003 Svend Sanjay Sorensen <ssorensen@fastmail.fm>
@ -36,7 +37,10 @@ extern "C" {
#define MIN_CDTEXT_FIELD 0 #define MIN_CDTEXT_FIELD 0
#define MAX_CDTEXT_FIELDS 10 #define MAX_CDTEXT_FIELDS 10
/*! Enumeration of CD-TEXT text fields. */ /*! \typedef enum cdtext_field_t
\brief Enumeration of CD-TEXT text fields.
*/
typedef enum { typedef enum {
CDTEXT_FIELD_TITLE = 0, /**< title of album name or track titles */ CDTEXT_FIELD_TITLE = 0, /**< title of album name or track titles */
CDTEXT_FIELD_PERFORMER = 1, /**< name(s) of the performer(s) */ CDTEXT_FIELD_PERFORMER = 1, /**< name(s) of the performer(s) */
@ -51,7 +55,10 @@ typedef enum {
CDTEXT_FIELD_INVALID = MAX_CDTEXT_FIELDS /**< INVALID FIELD*/ CDTEXT_FIELD_INVALID = MAX_CDTEXT_FIELDS /**< INVALID FIELD*/
} cdtext_field_t; } cdtext_field_t;
/*! Enumeration of possible genre codes. */ /*! \typedef enum cdtext_genre_t
\brief Enumeration of possible genre codes.
*/
typedef enum { typedef enum {
CDTEXT_GENRE_UNUSED = 0, /**< field is not used. default */ CDTEXT_GENRE_UNUSED = 0, /**< field is not used. default */
CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */ CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */
@ -84,10 +91,12 @@ typedef enum {
CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */ CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */
} cdtext_genre_t; } cdtext_genre_t;
/*! Enumeration of possible CD-TEXT languages. /*! \typedef typedef enum cdtext_lang_t
*
* The language code is encoded as specified in ANNEX 1 to part 5 of EBU \brief Enumeration of possible CD-TEXT languages.
* Tech 32 58 -E (1991).
The language code is encoded as specified in ANNEX 1 to part 5 of EBU
Tech 32 58 -E (1991).
*/ */
typedef enum { typedef enum {
CDTEXT_LANGUAGE_UNKNOWN = 0x00, CDTEXT_LANGUAGE_UNKNOWN = 0x00,
@ -192,11 +201,19 @@ typedef enum {
CDTEXT_LANGUAGE_ASSAMESE = 0x7C, CDTEXT_LANGUAGE_ASSAMESE = 0x7C,
CDTEXT_LANGUAGE_ARMENIAN = 0x7D, CDTEXT_LANGUAGE_ARMENIAN = 0x7D,
CDTEXT_LANGUAGE_ARABIC = 0x7E, CDTEXT_LANGUAGE_ARABIC = 0x7E,
CDTEXT_LANGUAGE_AMHARIC = 0x7F CDTEXT_LANGUAGE_AMHARIC = 0x7F,
/* libcdio-internal pseudo codes: */
CDTEXT_LANGUAGE_INVALID = 0x100, /**< Invalid language code */
CDTEXT_LANGUAGE_BLOCK_UNUSED = 0x101 /**< Language code should be ignored */
} cdtext_lang_t; } cdtext_lang_t;
/*! /*!
Opaque type for CD-Text. \typedef struct cdtext_s cdtext_t
\brief Opaque type for CD-Text.
*/ */
typedef struct cdtext_s cdtext_t; typedef struct cdtext_s cdtext_t;
@ -210,13 +227,25 @@ const char *cdtext_genre2str (cdtext_genre_t i);
*/ */
const char *cdtext_lang2str (cdtext_lang_t i); const char *cdtext_lang2str (cdtext_lang_t i);
/*!
Return the language code of a given language string representation.
This is the inverse of cdtext_lang2str().
@param lang language to look up
@return if lang is among the possible results of cdtext_lang2str():
the \p cdtext_lang_t which is associated, or \p
CDTEXT_LANGUAGE_INVALID otherwise.
*/
cdtext_lang_t cdtext_str2lang (const char *lang);
/*! /*!
Return string representation of given field type. Return string representation of given field type.
*/ */
const char *cdtext_field2str (cdtext_field_t i); const char *cdtext_field2str (cdtext_field_t i);
/*! /*!
Initialize a new cdtext structure. Initialize a new \p cdtext_t structure.
When the structure is no longer needed, release the When the structure is no longer needed, release the
resources using cdtext_delete. resources using cdtext_delete.
@ -224,7 +253,30 @@ const char *cdtext_field2str (cdtext_field_t i);
cdtext_t *cdtext_init (void); cdtext_t *cdtext_init (void);
/*! /*!
Read a binary CD-TEXT and fill a cdtext struct. Fill a cdtext_t object with text pack bytes as they were handed out by the
CD drive, but without the 4-byte header which the drive prepended.
The text pack data can be obtained by the calls
- cdio_get_cdtext_raw()
- mmc_read_cdtext()
- mmc_read_toc_cdtext()
Each sets in the buffer passed into values that begin with a 4-byte header. This should
be skipped. Here is some sample code:
@code
#include <cdio/mmc_ll_cmds.h>
if (DRIVER_OP_SUCCESS == mmc_read_toc_cdtext (p_cdio, &i_length, p_buf, 0)
&& 4 < i_length)
cdtext_data_init(p_cdtext, p_buf + 4, (size_t) i_length - 4);
@endcode
Instead of calling cdtext_data_init(), you can call
cdio_get_cdtext() which returns a pointer to the \p cdtext_t object
that is attached to the inquired \p CdIo_t object. This \p cdtext_t
object gets created and filled if none is yet attached to the
inquired \p CdIo_t object.
@param p_cdtext the CD-TEXT object @param p_cdtext the CD-TEXT object
@param wdata the data @param wdata the data
@ -235,7 +287,7 @@ cdtext_t *cdtext_init (void);
int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data); int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data);
/*! /*!
Free memory associated with the given cdtext_t object. Free memory associated with the given \p cdtext_t object.
@param p_cdtext the CD-TEXT object @param p_cdtext the CD-TEXT object
*/ */
@ -300,19 +352,65 @@ track_t cdtext_get_last_track(const cdtext_t *p_cdtext);
*/ */
bool cdtext_select_language(cdtext_t *p_cdtext, cdtext_lang_t language); bool cdtext_select_language(cdtext_t *p_cdtext, cdtext_lang_t language);
/* /*!
@deprecated Use cdtext_list_languages_v2()
Returns a list of available languages or NULL. Returns a list of available languages or NULL.
__WARNING__: The indices in the returned array _do not_ match the indexing
as expected by cdtext_set_language_index().
Use cdtext_select_language() with the values of array elements.
Internally the list is stored in a static array. Internally the list is stored in a static array.
@param p_cdtext the CD-TEXT object @param p_cdtext the CD-TEXT object
@return NULL if p_cdtext is NULL, or an array of 8 cdtext_lang_t elements:
CDTEXT_LANGUAGE_UNKNOWN not only marks language code 0x00
but also invalid language codes and invalid language blocks.
*/ */
cdtext_lang_t *cdtext_list_languages (const cdtext_t *p_cdtext); cdtext_lang_t *cdtext_list_languages (const cdtext_t *p_cdtext);
/*!
Returns an array of available languages or NULL.
The index of an array element may be used to select the corresponding
language block by call cdtext_set_language_index().
The return value is a pointer into the memory range of *p_cdtext.
Do not use it after having freed that memory range.
@param p_cdtext the CD-TEXT object
@return NULL if p_cdtext is NULL, or an array of 8 cdtext_lang_t elements.
If an enumeration is CDTEXT_LANGUAGE_INVALID, then the language block has an invalid
language code.
If an enumeration is CDTEXT_LANGUAGE_BLOCK_UNUSED, then the block does not
exist on CD or could not be read in CD-TEXT for some reason.
Otherwise, the enumeration of element will be a value in
CDTEXT_LANGUAGE_UNKNOWN to CDTEXT_LANGUAGE_AMHARIC, and is a block
in that language.
*/
cdtext_lang_t *cdtext_list_languages_v2(cdtext_t *p_cdtext);
/*!
Select the given language by block index. See cdtext_list_languages_v2().
If the index is bad, or no language block with that index was read:
select the default language at index 0 and return false.
@param p_cdtext the CD-TEXT object
@param idx the desired index: 0 to 7.
@return true on success, false if no language block is associated to \p idx.
*/
bool
cdtext_set_language_index(cdtext_t *p_cdtext, int idx);
/*! /*!
Sets the given field at the given track to the given value. Sets the given field at the given track to the given value.
Recodes to UTF-8 if charset is not NULL. Recodes to UTF-8 if charset is not \p NULL.
@param p_cdtext the CD-TEXT object @param p_cdtext the CD-TEXT object
@param key field to set @param key field to set

View file

@ -109,7 +109,7 @@ extern "C" {
/**< Has some sort of DVD or CD writing ability */ /**< Has some sort of DVD or CD writing ability */
} cdio_drive_cap_write_t; } cdio_drive_cap_write_t;
/** Size of fields returned by an INQUIRY command */ /** Size of fields returned by an \p INQUIRY command */
typedef enum { typedef enum {
CDIO_MMC_HW_VENDOR_LEN = 8, /**< length of vendor field */ CDIO_MMC_HW_VENDOR_LEN = 8, /**< length of vendor field */
CDIO_MMC_HW_MODEL_LEN = 16, /**< length of model field */ CDIO_MMC_HW_MODEL_LEN = 16, /**< length of model field */
@ -118,7 +118,7 @@ extern "C" {
/** \brief Structure to return CD vendor, model, and revision-level /** \brief Structure to return CD vendor, model, and revision-level
strings obtained via the INQUIRY command */ strings obtained via the \p INQUIRY command */
typedef struct cdio_hwinfo typedef struct cdio_hwinfo
{ {
char psz_vendor [CDIO_MMC_HW_VENDOR_LEN+1]; char psz_vendor [CDIO_MMC_HW_VENDOR_LEN+1];
@ -235,8 +235,9 @@ extern "C" {
@param psz_drive the name of CD-ROM to be closed. If NULL, we will @param psz_drive the name of CD-ROM to be closed. If NULL, we will
use the default device. use the default device.
@param p_driver_id is the driver to be used or that got used if @param p_driver_id is the driver to be used or that got used if
it was DRIVER_UNKNOWN or DRIVER_DEVICE; If this is NULL, we won't it was \p DRIVER_UNKNOWN or \p DRIVER_DEVICE; If this is \p NULL, we won't
report back the driver used. report back the driver used.
*/ */
driver_return_code_t cdio_close_tray (const char *psz_drive, driver_return_code_t cdio_close_tray (const char *psz_drive,
@ -244,7 +245,8 @@ extern "C" {
/** /**
@param drc the return code you want interpreted. @param drc the return code you want interpreted.
@return the string information about drc
@return the string information about \p drc
*/ */
const char *cdio_driver_errmsg(driver_return_code_t drc); const char *cdio_driver_errmsg(driver_return_code_t drc);
@ -252,7 +254,7 @@ extern "C" {
Eject media in CD drive if there is a routine to do so. Eject media in CD drive if there is a routine to do so.
@param p_cdio the CD object to be acted upon. @param p_cdio the CD object to be acted upon.
If the CD is ejected *p_cdio is free'd and p_cdio set to NULL. If the CD is ejected \p *p_cdio is free'd and p_cdio set to \p NULL.
*/ */
driver_return_code_t cdio_eject_media (CdIo_t **p_cdio); driver_return_code_t cdio_eject_media (CdIo_t **p_cdio);
@ -266,23 +268,24 @@ extern "C" {
/** /**
Free device list returned by cdio_get_devices or Free device list returned by cdio_get_devices or
cdio_get_devices_with_cap. cdio_get_devices_with_cap().
@param device_list list returned by cdio_get_devices or @param device_list list returned by cdio_get_devices or
cdio_get_devices_with_cap cdio_get_devices_with_cap().
@see cdio_get_devices, cdio_get_devices_with_cap @see cdio_get_devices(), and cdio_get_devices_with_cap().
*/ */
void cdio_free_device_list (char * device_list[]); void cdio_free_device_list (char * device_list[]);
/** /**
Get the default CD device. Get the default CD device.
if p_cdio is NULL (we haven't initialized a specific device driver), if \p p_cdio is \p NULL (we haven't initialized a specific device driver),
then find a suitable one and return the default device for that. then find a suitable one and return the default device for that.
@param p_cdio the CD object queried @param p_cdio the CD object queried
@return a string containing the default CD device or NULL is
@return a string containing the default CD device or \p NULL
if we couldn't get a default device. if we couldn't get a default device.
In some situations of drivers or OS's we can't find a CD device if In some situations of drivers or OS's we can't find a CD device if
@ -293,30 +296,30 @@ extern "C" {
/** /**
Return a string containing the default CD device if none is specified. Return a string containing the default CD device if none is specified.
if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE if \p p_driver_id is \p DRIVER_UNKNOWN or \p DRIVER_DEVICE
then find a suitable one set the default device for that. then find a suitable one set the default device for that.
NULL is returned if we couldn't get a default device. \p NULL is returned if we couldn't get a default device.
*/ */
char * cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id); char * cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id);
/** Return an array of device names. If you want a specific /** Return an array of device names. If you want a specific
devices for a driver, give that device. If you want hardware devices for a driver, give that device. If you want hardware
devices, give DRIVER_DEVICE and if you want all possible devices, devices, give \p DRIVER_DEVICE and if you want all possible devices,
image drivers and hardware drivers give DRIVER_UNKNOWN. image drivers and hardware drivers give \p DRIVER_UNKNOWN.
NULL is returned if we couldn't return a list of devices. NULL is returned if we couldn't return a list of devices.
In some situations of drivers or OS's we can't find a CD device if In some situations of drivers or OS's we can't find a CD device if
there is no media in it and it is possible for this routine to return there is no media in it and it is possible for this routine to return
NULL even though there may be a hardware CD-ROM. \p NULL even though there may be a hardware CD-ROM.
*/ */
char ** cdio_get_devices (driver_id_t driver_id); char ** cdio_get_devices (driver_id_t driver_id);
/** /**
Get an array of device names in search_devices that have at least Get an array of device names in search_devices that have at least
the capabilities listed by the capabities parameter. If the capabilities listed by the capabities parameter. If
search_devices is NULL, then we'll search all possible CD drives. search_devices is \p NULL, then we'll search all possible CD drives.
Capabilities have two parts to them, a "filesystem" part and an Capabilities have two parts to them, a "filesystem" part and an
"analysis" part. "analysis" part.
@ -353,7 +356,7 @@ extern "C" {
cdio_fs_anal_t capabilities, bool b_any); cdio_fs_anal_t capabilities, bool b_any);
/** /**
Like cdio_get_devices_with_cap but we return the driver we found Like cdio_get_devices_with_cap() but we return the driver we found
as well. This is because often one wants to search for kind of drive as well. This is because often one wants to search for kind of drive
and then *open* it afterwards. Giving the driver back facilitates this, and then *open* it afterwards. Giving the driver back facilitates this,
and speeds things up for libcdio as well. and speeds things up for libcdio as well.
@ -364,8 +367,8 @@ extern "C" {
/*out*/ driver_id_t *p_driver_id); /*out*/ driver_id_t *p_driver_id);
/** /**
Like cdio_get_devices, but we may change the p_driver_id if we Like cdio_get_devices(), but we may change the p_driver_id if we
were given DRIVER_DEVICE or DRIVER_UNKNOWN. This is because often were given \p DRIVER_DEVICE or \p DRIVER_UNKNOWN. This is because often
one wants to get a drive name and then *open* it one wants to get a drive name and then *open* it
afterwards. Giving the driver back facilitates this, and speeds afterwards. Giving the driver back facilitates this, and speeds
things up for libcdio as well. things up for libcdio as well.
@ -383,7 +386,7 @@ extern "C" {
In some situations of drivers or OS's we can't find a CD device if In some situations of drivers or OS's we can't find a CD device if
there is no media in it. In this situation capabilities will show up as there is no media in it. In this situation capabilities will show up as
NULL even though there isa hardware CD-ROM. \p NULL even though there isa hardware CD-ROM.
*/ */
void cdio_get_drive_cap (const CdIo_t *p_cdio, void cdio_get_drive_cap (const CdIo_t *p_cdio,
cdio_drive_read_cap_t *p_read_cap, cdio_drive_read_cap_t *p_read_cap,
@ -397,7 +400,7 @@ extern "C" {
In some situations of drivers or OS's we can't find a CD device if In some situations of drivers or OS's we can't find a CD device if
there is no media in it. In this situation capabilities will show up as there is no media in it. In this situation capabilities will show up as
NULL even though there isa hardware CD-ROM. \p NULL even though there isa hardware CD-ROM.
*/ */
void cdio_get_drive_cap_dev (const char *device, void cdio_get_drive_cap_dev (const char *device,
cdio_drive_read_cap_t *p_read_cap, cdio_drive_read_cap_t *p_read_cap,
@ -407,23 +410,25 @@ extern "C" {
/** /**
Get a string containing the name of the driver in use. Get a string containing the name of the driver in use.
@param p_cdio the CD object to be acted upon.
@return a string with driver name or NULL if CdIo_t is NULL (we @return a string with driver name or NULL if CdIo_t is NULL (we
haven't initialized a specific device. haven't initialized a specific device.
*/ */
const char * cdio_get_driver_name (const CdIo_t *p_cdio); const char * cdio_get_driver_name (const CdIo_t *p_cdio);
/** /**
Return a string containing the name of the driver in use from the driver_id. Return a string name for the \p driver_id.
if CdIo is NULL (we haven't initialized a specific device driver),
then return NULL.
*/ */
const char * cdio_get_driver_name_from_id (driver_id_t driver_id); const char * cdio_get_driver_name_from_id (driver_id_t driver_id);
/** /**
Get the driver id. Get the driver id.
if CdIo_t is NULL (we haven't initialized a specific device driver), if \p p_cdio is \p NULL (we haven't initialized a specific device driver),
then return DRIVER_UNKNOWN. then return \p DRIVER_UNKNOWN.
@param p_cdio the CD object to be acted upon.
@return the driver id.. @return the driver id..
*/ */
@ -449,9 +454,11 @@ extern "C" {
/** /**
Find out if media has changed since the last call. Find out if media has changed since the last call.
@param p_cdio the CD object to be acted upon. @param p_cdio the CD object to be acted upon.
@return 1 if media has changed since last call, 0 if not. Error @return 1 if media has changed since last call, 0 if not. Error
return codes are the same as driver_return_code_t return codes are the same as \p driver_return_code_t
*/ */
int cdio_get_media_changed(CdIo_t *p_cdio); int cdio_get_media_changed(CdIo_t *p_cdio);
@ -462,7 +469,7 @@ extern "C" {
bool cdio_have_driver (driver_id_t driver_id); bool cdio_have_driver (driver_id_t driver_id);
/** /**
Free any resources associated with p_cdio. Call this when done Free any resources associated with \p p_cdio. Call this when done
using p_cdio and using CD reading/control operations. using p_cdio and using CD reading/control operations.
@param p_cdio the CD object to eliminated. @param p_cdio the CD object to eliminated.
@ -478,8 +485,8 @@ extern "C" {
const char *cdio_driver_describe (driver_id_t driver_id); const char *cdio_driver_describe (driver_id_t driver_id);
/** /**
Sets up to read from place specified by psz_source and Sets up to read from place specified by \p psz_source and
driver_id. This or cdio_open_* should be called before using any \p driver_id. This or cdio_open_* should be called before using any
other routine, except cdio_init or any routine that accesses the other routine, except cdio_init or any routine that accesses the
CD-ROM drive by name. cdio_open will call cdio_init, if that CD-ROM drive by name. cdio_open will call cdio_init, if that
hasn't been done previously. hasn't been done previously.
@ -496,9 +503,10 @@ extern "C" {
CD-ROM drive by name. This will call cdio_init, if that hasn't CD-ROM drive by name. This will call cdio_init, if that hasn't
been done previously. been done previously.
If NULL is given as the source, we'll use the default driver device. If \p NULL is given as the source, we'll use the default driver
device.
@return the cdio object or NULL on error or no device. @return the cdio object or \p NULL on error or no device.
*/ */
CdIo_t * cdio_open_am (const char *psz_source, CdIo_t * cdio_open_am (const char *psz_source,
driver_id_t driver_id, const char *psz_access_mode); driver_id_t driver_id, const char *psz_access_mode);
@ -507,7 +515,7 @@ extern "C" {
Set up BIN/CUE CD disk-image for reading. Source is the .bin or Set up BIN/CUE CD disk-image for reading. Source is the .bin or
.cue file .cue file
@return the cdio object or NULL on error or no device. @return the cdio object or \p NULL on error or no device.
*/ */
CdIo_t * cdio_open_bincue (const char *psz_cue_name); CdIo_t * cdio_open_bincue (const char *psz_cue_name);
@ -515,7 +523,7 @@ extern "C" {
Set up BIN/CUE CD disk-image for reading. Source is the .bin or Set up BIN/CUE CD disk-image for reading. Source is the .bin or
.cue file .cue file
@return the cdio object or NULL on error or no device.. @return the cdio object or \p NULL on error or no device..
*/ */
CdIo_t * cdio_open_am_bincue (const char *psz_cue_name, CdIo_t * cdio_open_am_bincue (const char *psz_cue_name,
const char *psz_access_mode); const char *psz_access_mode);
@ -523,7 +531,7 @@ extern "C" {
/** /**
Set up cdrdao CD disk-image for reading. Source is the .toc file Set up cdrdao CD disk-image for reading. Source is the .toc file
@return the cdio object or NULL on error or no device. @return the cdio object or \p NULL on error or no device.
*/ */
CdIo_t * cdio_open_cdrdao (const char *psz_toc_name); CdIo_t * cdio_open_cdrdao (const char *psz_toc_name);
@ -539,7 +547,7 @@ extern "C" {
Return a string containing the default CUE file that would Return a string containing the default CUE file that would
be used when none is specified. be used when none is specified.
@return the cdio object or NULL on error or no device. @return the cdio object or \p NULL on error or no device.
*/ */
char * cdio_get_default_device_bincue(void); char * cdio_get_default_device_bincue(void);
@ -547,7 +555,7 @@ extern "C" {
/** /**
@return string containing the default CUE file that would be @return string containing the default CUE file that would be
used when none is specified. NULL is returned on error or there used when none is specified. \p NULL is returned on error or there
is no device. is no device.
*/ */
char * cdio_get_default_device_cdrdao(void); char * cdio_get_default_device_cdrdao(void);
@ -559,7 +567,7 @@ extern "C" {
the some sort of device name. the some sort of device name.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no driver for a some sort of hardware CD-ROM. \p NULL on error or there is no driver for a some sort of hardware CD-ROM.
*/ */
CdIo_t * cdio_open_cd (const char *device_name); CdIo_t * cdio_open_cd (const char *device_name);
@ -568,7 +576,7 @@ extern "C" {
the some sort of device name. the some sort of device name.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no driver for a some sort of hardware CD-ROM. \p NULL on error or there is no driver for a some sort of hardware CD-ROM.
*/ */
CdIo_t * cdio_open_am_cd (const char *psz_device, CdIo_t * cdio_open_am_cd (const char *psz_device,
const char *psz_access_mode); const char *psz_access_mode);
@ -577,7 +585,7 @@ extern "C" {
CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error. \p NULL on error.
*/ */
CdIo_t * cdio_open_cue (const char *cue_name); CdIo_t * cdio_open_cue (const char *cue_name);
@ -586,9 +594,9 @@ extern "C" {
the some sort of device name. the some sort of device name.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no AIX driver. \p NULL on error or there is no AIX driver.
@see cdio_open @see cdio_open()
*/ */
CdIo_t * cdio_open_am_aix (const char *psz_source, CdIo_t * cdio_open_am_aix (const char *psz_source,
const char *psz_access_mode); const char *psz_access_mode);
@ -598,9 +606,9 @@ extern "C" {
the some sort of device name. the some sort of device name.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no AIX driver. \p NULL on error or there is no AIX driver.
@see cdio_open @see cdio_open()
*/ */
CdIo_t * cdio_open_aix (const char *psz_source); CdIo_t * cdio_open_aix (const char *psz_source);
@ -609,9 +617,9 @@ extern "C" {
driver would use when none is specified. driver would use when none is specified.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no AIX driver. \p NULL on error or there is no AIX driver.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
char * cdio_get_default_device_aix(void); char * cdio_get_default_device_aix(void);
@ -621,62 +629,17 @@ extern "C" {
In some situations of drivers or OS's we can't find a CD device In some situations of drivers or OS's we can't find a CD device
if there is no media in it and it is possible for this routine to if there is no media in it and it is possible for this routine to
return NULL even though there may be a hardware CD-ROM. return \p NULL even though there may be a hardware CD-ROM.
*/ */
char **cdio_get_devices_aix(void); char **cdio_get_devices_aix(void);
/**
Set up CD-ROM for reading using the BSDI driver. The device_name
is the some sort of device name.
@param psz_source the name of the device to open
@return the cdio object for subsequent operations.
NULL on error or there is no BSDI driver.
@see cdio_open
*/
CdIo_t * cdio_open_bsdi (const char *psz_source);
/**
Set up CD-ROM for reading using the BSDI driver. The device_name
is the some sort of device name.
@return the cdio object for subsequent operations.
NULL on error or there is no BSDI driver.
@see cdio_open
*/
CdIo_t * cdio_open_am_bsdi (const char *psz_source,
const char *psz_access_mode);
/**
Return a string containing the default device name that the BSDI
driver would use when none is specified.
@return the cdio object for subsequent operations.
NULL on error or there is no BSDI driver.
@see cdio_open_cd, cdio_open
*/
char * cdio_get_default_device_bsdi(void);
/**
Return a list of all of the CD-ROM devices that the BSDI driver
can find.
In some situations of drivers or OS's we can't find a CD device
if there is no media in it and it is possible for this routine to
return NULL even though there may be a hardware CD-ROM.
*/
char **cdio_get_devices_bsdi(void);
/** /**
Set up CD-ROM for reading using the FreeBSD driver. The Set up CD-ROM for reading using the FreeBSD driver. The
device_name is the some sort of device name. device_name is the some sort of device name.
NULL is returned on error or there is no FreeBSD driver. NULL is returned on error or there is no FreeBSD driver.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
CdIo_t * cdio_open_freebsd (const char *paz_psz_source); CdIo_t * cdio_open_freebsd (const char *paz_psz_source);
@ -686,7 +649,7 @@ extern "C" {
NULL is returned on error or there is no FreeBSD driver. NULL is returned on error or there is no FreeBSD driver.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
CdIo_t * cdio_open_am_freebsd (const char *psz_source, CdIo_t * cdio_open_am_freebsd (const char *psz_source,
const char *psz_access_mode); const char *psz_access_mode);
@ -754,7 +717,7 @@ extern "C" {
device_name is the some sort of device name. device_name is the some sort of device name.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no Solaris driver. \p NULL on error or there is no Solaris driver.
*/ */
CdIo_t * cdio_open_solaris (const char *psz_source); CdIo_t * cdio_open_solaris (const char *psz_source);
@ -763,7 +726,7 @@ extern "C" {
device_name is the some sort of device name. device_name is the some sort of device name.
@return the cdio object for subsequent operations. @return the cdio object for subsequent operations.
NULL on error or there is no Solaris driver. \p NULL on error or there is no Solaris driver.
*/ */
CdIo_t * cdio_open_am_solaris (const char *psz_source, CdIo_t * cdio_open_am_solaris (const char *psz_source,
const char *psz_access_mode); const char *psz_access_mode);
@ -773,13 +736,13 @@ extern "C" {
Solaris driver would use when none is specified. A scan is made Solaris driver would use when none is specified. A scan is made
for CD-ROM drives with CDs in them. for CD-ROM drives with CDs in them.
NULL is returned on error or there is no CD-ROM device. \p NULL is returned on error or there is no CD-ROM device.
In some situations of drivers or OS's we can't find a CD device if In some situations of drivers or OS's we can't find a CD device if
there is no media in it and it is possible for this routine to return there is no media in it and it is possible for this routine to return
NULL even though there may be a hardware CD-ROM. \p NULL even though there may be a hardware CD-ROM.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
char * cdio_get_default_device_solaris(void); char * cdio_get_default_device_solaris(void);
@ -793,13 +756,13 @@ extern "C" {
Set up CD-ROM for reading using the Apple OSX driver. The Set up CD-ROM for reading using the Apple OSX driver. The
device_name is the some sort of device name. device_name is the some sort of device name.
NULL is returned on error or there is no OSX driver. \p NULL is returned on error or there is no OSX driver.
In some situations of drivers or OS's we can't find a CD device if In some situations of drivers or OS's we can't find a CD device if
there is no media in it and it is possible for this routine to return there is no media in it and it is possible for this routine to return
NULL even though there may be a hardware CD-ROM. NULL even though there may be a hardware CD-ROM.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
CdIo_t * cdio_open_osx (const char *psz_source); CdIo_t * cdio_open_osx (const char *psz_source);
@ -809,7 +772,7 @@ extern "C" {
NULL is returned on error or there is no OSX driver. NULL is returned on error or there is no OSX driver.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
CdIo_t * cdio_open_am_osx (const char *psz_source, CdIo_t * cdio_open_am_osx (const char *psz_source,
const char *psz_access_mode); const char *psz_access_mode);
@ -859,54 +822,12 @@ extern "C" {
if there is no media in it and it is possible for this routine to if there is no media in it and it is possible for this routine to
return NULL even though there may be a hardware CD-ROM. return NULL even though there may be a hardware CD-ROM.
@see cdio_open_cd, cdio_open @see cdio_open_cd(), cdio_open()
*/ */
char * cdio_get_default_device_win32(void); char * cdio_get_default_device_win32(void);
char **cdio_get_devices_win32(void); char **cdio_get_devices_win32(void);
/**
Set up CD-ROM for reading using the IBM OS/2 driver. The
device_name is the some sort of device name.
NULL is returned on error or there is no OS/2 driver.
In some situations of drivers or OS's we can't find a CD device if
there is no media in it and it is possible for this routine to return
NULL even though there may be a hardware CD-ROM.
@see cdio_open_cd, cdio_open
*/
CdIo_t * cdio_open_os2 (const char *psz_source);
/**
Set up CD-ROM for reading using the IBM OS/2 driver. The
device_name is the some sort of device name.
NULL is returned on error or there is no OS/2 driver.
@see cdio_open_cd, cdio_open
*/
CdIo_t * cdio_open_am_os2 (const char *psz_source,
const char *psz_access_mode);
/**
Return a string containing the default device name that the OS/2
driver would use when none is specified. A scan is made for
CD-ROM drives with CDs in them.
In some situations of drivers or OS's we can't find a CD device
if there is no media in it and it is possible for this routine to
return NULL even though there may be a hardware CD-ROM.
*/
char * cdio_get_default_device_os2(void);
/**
Return a list of all of the CD-ROM devices that the OS/2 driver
can find.
*/
char **cdio_get_devices_os2(void);
/** /**
Set up CD-ROM for reading using the Nero driver. The device_name Set up CD-ROM for reading using the Nero driver. The device_name
is the some sort of device name. is the some sort of device name.
@ -942,7 +863,7 @@ Return a list of all of the CD-ROM devices that the OS/2 driver
@param bin_name location of presumed CDRWIN bin image file. @param bin_name location of presumed CDRWIN bin image file.
@return the corresponding CUE file if bin_name is a BIN file or @return the corresponding CUE file if bin_name is a BIN file or
NULL if not a BIN file. \p NULL if not a BIN file.
*/ */
char *cdio_is_binfile(const char *bin_name); char *cdio_is_binfile(const char *bin_name);
@ -950,7 +871,7 @@ Return a list of all of the CD-ROM devices that the OS/2 driver
Determine if cue_name is the cue sheet for a CDRWIN CD disk image. Determine if cue_name is the cue sheet for a CDRWIN CD disk image.
@return corresponding BIN file if cue_name is a CDRWIN cue file or @return corresponding BIN file if cue_name is a CDRWIN cue file or
NULL if not a CUE file. \p NULL if not a CUE file.
*/ */
char *cdio_is_cuefile(const char *cue_name); char *cdio_is_cuefile(const char *cue_name);
@ -1003,7 +924,7 @@ Return a list of all of the CD-ROM devices that the OS/2 driver
value too large will result in using the value too large will result in using the
fastest speed. fastest speed.
@see mmc_set_speed and mmc_set_drive_speed @see mmc_set_speed() and mmc_set_drive_speed()
*/ */
driver_return_code_t cdio_set_speed ( const CdIo_t *p_cdio, driver_return_code_t cdio_set_speed ( const CdIo_t *p_cdio,
int i_drive_speed ); int i_drive_speed );
@ -1011,10 +932,9 @@ Return a list of all of the CD-ROM devices that the OS/2 driver
/** /**
Get the value associatied with key. Get the value associatied with key.
@param p_cdio the CD object queried @param p_cdio the CD object queried @param key the key to
@param key the key to retrieve retrieve @return the value associated with "key", \p NULL if \p
@return the value associatd with "key" or NULL if p_cdio is NULL p_cdio is \p NULL, or "key" does not exist.
or "key" does not exist.
*/ */
const char * cdio_get_arg (const CdIo_t *p_cdio, const char key[]); const char * cdio_get_arg (const CdIo_t *p_cdio, const char key[]);

View file

@ -1,5 +1,6 @@
/* -*- c -*- /* -*- c -*-
Copyright (C) 2018 Thomas Schmitt
Copyright (C) 2004, 2005, 2006, 2008, 2010, 2012, 2014 Copyright (C) 2004, 2005, 2006, 2008, 2010, 2012, 2014
Rocky Bernstein <rocky@gnu.org> Rocky Bernstein <rocky@gnu.org>
@ -58,21 +59,28 @@ extern "C" {
extern const char *discmode2str[]; extern const char *discmode2str[];
/** /**
Get binary CD-Text information for a CdIo_t object. Read cdtext information for a cdtext_t object.
About format and usage of these data see the documentation of call
mmc_read_cdtext() in include file <cdio/mmc.h>.
@param p_cdio the CD object that may contain CD-Text information. @param p_cdio the CD object that may contain CD-Text information.
@return malloc'd pointer to raw CD-Text data as stored on the disc or @return malloc'd pointer to raw CD-Text data as replied by the drive
NULL if p_cdio is NULL or CD-Text information does not exist. Return or NULL if problems occur or CD-Text information does not exist.
value must be freed with cdio_free() when done with it and not NULL. A non-NULL return value must be freed with cdio_free() when done.
*/ */
uint8_t * cdio_get_cdtext_raw (CdIo_t *p_cdio); uint8_t * cdio_get_cdtext_raw (CdIo_t *p_cdio);
/** /**
Get CD-Text information for a CdIo_t object. Return a pointer to the cdtext_t object which is attached to a CdIo_t
object. If no such cdtext_t is attached yet, then try to read CD-TEXT
information and use it to create and initialise the cdtext_t object.
For usage of cdtext_t see include file <cdio/cdtext.h>.
@param p_cdio the CD object that may contain CD-Text information. @param p_cdio the CD object that may contain CD-Text information.
@return the CD-Text object or NULL if p_cdio is NULL @return a pointer to the attached cdtext_t object or NULL if problems
or CD-Text information does not exist. occur or if CD-Text information does not exist.
*/ */
cdtext_t *cdio_get_cdtext (CdIo_t *p_cdio); cdtext_t *cdio_get_cdtext (CdIo_t *p_cdio);

View file

@ -156,9 +156,6 @@ 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.
*/ */
@ -166,6 +163,8 @@ extern const char ISO_STANDARD_ID[sizeof("CD001")-1];
#define ISO_STANDARD_ID "CD001" #define ISO_STANDARD_ID "CD001"
#define CDIO_EXTENT_BLOCKS(size) ((size + (ISO_BLOCKSIZE - 1)) / ISO_BLOCKSIZE)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
@ -536,14 +535,33 @@ struct iso9660_stat_s { /* big endian!! */
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? */
uint64_t size; /**< total size in bytes */ lsn_t lsn; /**< start logical sector number */
uint8_t extents; /**< number of multiextents */
/**⌵ start logical sector number for each extent */ #ifndef DO_NOT_WANT_COMPATIBILITY
lsn_t lsn[ISO_MAX_MULTIEXTENT];
/**⌵ size of each extent */ /* *** Deprecated Legacy API ***
uint32_t extsize[ISO_MAX_MULTIEXTENT]; Use .total_size and CDIO_EXTENT_BLOCKS.
/**⌵ number of sectors allocated for each extent */ */
uint32_t secsize[ISO_MAX_MULTIEXTENT]; uint32_t size; /**< size of the first extent, in bytes */
uint32_t secsize; /**< size of the first extent, in sectors */
#endif /* DO_NOT_WANT_COMPATIBILITY */
/* Multi-extent aware size, in bytes.
It is guaranteed that the bytes are stored as gapless string in a
continguous sequence of blocks. I.e. they can be read sequentially
starting at iso9660_stat_s.lsn.
Data files which do not fulfil this promise cause a warning message
and are not represented by this type of struct.
(Directories are not allowed to have more than one extent and thus cannot
legally break the promise.)
*/
uint64_t total_size;
/* NB: If you need to access the 'secsize' equivalent for an extent,
* you should use CDIO_EXTENT_BLOCKS(iso9660_stat_s.total_size) */
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;

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2012, 2017 Copyright (C) 2002-2008, 2012, 2017 2019
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,6 +27,8 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#else
# include <stdbool.h>
#endif /* __cplusplus */ #endif /* __cplusplus */
/* If <sys/types.h> is not available on your platform please /* If <sys/types.h> is not available on your platform please
@ -103,27 +105,6 @@ typedef uint8_t ubyte;
# endif # endif
#endif #endif
#ifndef __cplusplus
/* All the stdbool.h seem to define those */
#ifndef __bool_true_false_are_defined
#define __bool_true_false_are_defined 1
#undef bool
#undef true
#undef false
#ifdef _Bool
#define bool _Bool
#else
#define bool unsigned char
#endif
#define true 1
#define false 0
#endif /* __bool_true_false_are_defined */
#endif /*C++*/
/* some GCC optimizations -- gcc 2.5+ */ /* some GCC optimizations -- gcc 2.5+ */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
@ -151,7 +132,7 @@ typedef uint8_t ubyte;
#define GNUC_PACKED #define GNUC_PACKED
#endif /* !__GNUC__ */ #endif /* !__GNUC__ */
#if defined(__MINGW32__) #if defined(__MINGW32__) || (defined( __clang_major__) && __clang_major__ > 9)
# define PRAGMA_BEGIN_PACKED _Pragma("pack(push)") \ # define PRAGMA_BEGIN_PACKED _Pragma("pack(push)") \
_Pragma("pack(1)") _Pragma("pack(1)")
# define PRAGMA_END_PACKED _Pragma("pack(pop)") # define PRAGMA_END_PACKED _Pragma("pack(pop)")

View file

@ -7,7 +7,7 @@
/*! CDIO_VERSION is a C-Preprocessor macro of a string that shows what /*! CDIO_VERSION is a C-Preprocessor macro of a string that shows what
version is used. cdio_version_string has the same value, but it is a version is used. cdio_version_string has the same value, but it is a
constant variable that can be accessed at run time. */ constant variable that can be accessed at run time. */
#define CDIO_VERSION "2.0.0 (Rufus)" #define CDIO_VERSION "2.1.0 (Rufus)"
extern const char *cdio_version_string; /**< = CDIO_VERSION */ extern const char *cdio_version_string; /**< = CDIO_VERSION */
/*! LIBCDIO_VERSION_NUM is a C-Preprocessor macro that can be used for /*! LIBCDIO_VERSION_NUM is a C-Preprocessor macro that can be used for

View file

@ -71,7 +71,9 @@ extern "C" {
XA_FORM2_FILE = (XA_ATTR_MODE2FORM2 | XA_PERM_ALL_ALL) XA_FORM2_FILE = (XA_ATTR_MODE2FORM2 | XA_PERM_ALL_ALL)
} xa_misc_enum_t; } xa_misc_enum_t;
extern const char ISO_XA_MARKER_STRING[8]; extern const char ISO_XA_MARKER_STRING[sizeof("CD-XA001")-1];
#define ISO_XA_MARKER_STRING "CD-XA001"
/*! \brief "Extended Architecture" according to the Philips Yellow Book. /*! \brief "Extended Architecture" according to the Philips Yellow Book.

View file

@ -48,6 +48,9 @@
/* Define if you have the iconv() function and it works. */ /* Define if you have the iconv() function and it works. */
/* #undef HAVE_ICONV */ /* #undef HAVE_ICONV */
/* Define this if you want to use the 2020 version of the libcdio API. */
#define DO_NOT_WANT_COMPATIBILITY /**/
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1 /* provided in MSVC/missing if needed */ #define HAVE_INTTYPES_H 1 /* provided in MSVC/missing if needed */

View file

@ -187,7 +187,7 @@ cdio_read_mode1_sector (const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
return p_cdio->op.read_mode1_sector(p_cdio->env, p_buf, i_lsn, b_form2); return p_cdio->op.read_mode1_sector(p_cdio->env, p_buf, i_lsn, b_form2);
} else if (p_cdio->op.lseek && p_cdio->op.read) { } else if (p_cdio->op.lseek && p_cdio->op.read) {
char buf[M2RAW_SECTOR_SIZE] = { 0, }; char buf[M2RAW_SECTOR_SIZE] = { 0, };
if (0 > cdio_lseek(p_cdio, (long long)CDIO_CD_FRAMESIZE * i_lsn, SEEK_SET)) if (0 > cdio_lseek(p_cdio, (off_t)CDIO_CD_FRAMESIZE * i_lsn, SEEK_SET))
return -1; return -1;
if (0 > cdio_read(p_cdio, buf, CDIO_CD_FRAMESIZE)) if (0 > cdio_read(p_cdio, buf, CDIO_CD_FRAMESIZE))
return -1; return -1;

View file

@ -373,6 +373,9 @@ iso9660_set_ltime_with_timezone(const struct tm *p_tm,
if (!p_tm) return; if (!p_tm) return;
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
snprintf(_pvd_date, 17, snprintf(_pvd_date, 17,
"%4.4d%2.2d%2.2d" "%2.2d%2.2d%2.2d" "%2.2d", "%4.4d%2.2d%2.2d" "%2.2d%2.2d%2.2d" "%2.2d",
p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday, p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday,
@ -632,7 +635,8 @@ iso9660_set_pvd(void *pd,
memset(&ipd,0,sizeof(ipd)); /* paranoia? */ memset(&ipd,0,sizeof(ipd)); /* paranoia? */
/* magic stuff ... thatis CD XA marker... */ /* magic stuff ... thatis CD XA marker... */
strncpy(((char*)&ipd)+ISO_XA_MARKER_OFFSET, ISO_XA_MARKER_STRING,8); strncpy(((char*)&ipd)+ISO_XA_MARKER_OFFSET, ISO_XA_MARKER_STRING,
strlen(ISO_XA_MARKER_STRING)+1);
ipd.type = to_711(ISO_VD_PRIMARY); ipd.type = to_711(ISO_VD_PRIMARY);
iso9660_strncpy_pad (ipd.id, ISO_STANDARD_ID, 5, ISO9660_DCHARS); iso9660_strncpy_pad (ipd.id, ISO_STANDARD_ID, 5, ISO9660_DCHARS);

View file

@ -1,5 +1,7 @@
/* /*
Copyright (C) 2003-2008, 2011-2015, 2017 Rocky Bernstein <rocky@gnu.org> Copyright (C) 2003-2008, 2011-2015, 2017 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2018, 2020 Pete Batard <pete@akeo.ie>
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>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -789,40 +791,66 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
iso9660_stat_t *p_stat = last_p_stat; iso9660_stat_t *p_stat = last_p_stat;
char rr_fname[256] = ""; char rr_fname[256] = "";
int i_rr_fname; int i_rr_fname;
lsn_t extent_lsn;
bool first_extent;
if (!dir_len) return NULL; if (!dir_len) return NULL;
i_fname = from_711(p_iso9660_dir->filename.len); i_fname = from_711(p_iso9660_dir->filename.len);
/* .. 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;
/* Reuse multiextent p_stat if not NULL */ /* Reuse multiextent p_stat if not NULL */
if (!p_stat) if (!p_stat) {
p_stat = calloc(1, stat_len); p_stat = calloc(1, stat_len);
if (!p_stat) first_extent = true;
{ } else {
first_extent = false;
}
if (!p_stat) {
cdio_warn("Couldn't calloc(1, %d)", stat_len); cdio_warn("Couldn't calloc(1, %d)", stat_len);
return NULL; return NULL;
} }
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[p_stat->extents] = from_733 (p_iso9660_dir->extent);
p_stat->extsize[p_stat->extents] = from_733 (p_iso9660_dir->size); /* Test for gaps between extents. Important: Use previous .total_size */
p_stat->size += p_stat->extsize[p_stat->extents]; extent_lsn = from_733 (p_iso9660_dir->extent);
p_stat->secsize[p_stat->extents] = _cdio_len2blocks (p_stat->extsize[p_stat->extents], ISO_BLOCKSIZE); if (p_stat->total_size > 0) {
/* This is a follow-up extent. Check for a gap. */
if (p_stat->lsn + p_stat->total_size / ISO_BLOCKSIZE != extent_lsn
|| p_stat->total_size % ISO_BLOCKSIZE) {
/* Gap detected. Throw error. */
cdio_warn("Non-contiguous data extents with '%s'", p_stat->filename);
goto fail;
}
} else if (first_extent) {
p_stat->lsn = extent_lsn;
}
/* 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 */ p_stat->rr.b3_rock = dunno; /*FIXME should do based on mask */
p_stat->b_xa = false; p_stat->b_xa = false;
#ifndef DO_NOT_WANT_COMPATIBILITY
if (first_extent) {
p_stat->size = from_733(p_iso9660_dir->size);
p_stat->secsize = CDIO_EXTENT_BLOCKS(p_stat->size);
}
#endif /* DO_NOT_WANT_COMPATIBILITY */
/* Only resolve the full filename when we're not dealing with extent */ /* 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 */ /* Check if this is the last part of a multiextent file */
if (p_stat->extents != 0) { if (!first_extent) {
if (strcmp(p_stat->filename, &p_iso9660_dir->filename.str[1]) != 0) { if (strlen(p_stat->filename) != i_fname ||
cdio_warn("Warning: Non consecutive multiextent file parts for '%s'", p_stat->filename); strncmp(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname) != 0) {
free(p_stat); cdio_warn("Non consecutive multiextent file parts for '%s'",
return NULL; p_stat->filename);
goto fail;
} }
} }
i_rr_fname = i_rr_fname =
@ -837,11 +865,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
/* realloc gives valgrind errors */ /* realloc gives valgrind errors */
iso9660_stat_t *p_stat_new = iso9660_stat_t *p_stat_new =
calloc(1, sizeof(iso9660_stat_t)+i_rr_fname+2); calloc(1, sizeof(iso9660_stat_t)+i_rr_fname+2);
if (!p_stat_new) if (!p_stat_new) {
{
cdio_warn("Couldn't calloc(1, %d)", (int)(sizeof(iso9660_stat_t)+i_rr_fname+2)); cdio_warn("Couldn't calloc(1, %d)", (int)(sizeof(iso9660_stat_t)+i_rr_fname+2));
free(p_stat); goto fail;
return NULL;
} }
memcpy(p_stat_new, p_stat, stat_len); memcpy(p_stat_new, p_stat, stat_len);
free(p_stat); free(p_stat);
@ -850,9 +876,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
strncpy(p_stat->filename, rr_fname, i_rr_fname+1); strncpy(p_stat->filename, rr_fname, i_rr_fname+1);
} else { } else {
if ('\0' == p_iso9660_dir->filename.str[1] && 1 == i_fname) if ('\0' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
strncpy (p_stat->filename, ".", 2); strncpy (p_stat->filename, ".", strlen(".")+1);
else if ('\1' == p_iso9660_dir->filename.str[1] && 1 == i_fname) else if ('\1' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
strncpy (p_stat->filename, "..", 3); strncpy (p_stat->filename, "..", strlen("..")+1);
#ifdef HAVE_JOLIET #ifdef HAVE_JOLIET
else if (u_joliet_level) { else if (u_joliet_level) {
int i_inlen = i_fname; int i_inlen = i_fname;
@ -861,10 +887,8 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
&p_psz_out, "UCS-2BE")) { &p_psz_out, "UCS-2BE")) {
strncpy(p_stat->filename, p_psz_out, i_fname); strncpy(p_stat->filename, p_psz_out, i_fname);
free(p_psz_out); free(p_psz_out);
} } else {
else { goto fail;
free(p_stat);
return NULL;
} }
} }
#endif /*HAVE_JOLIET*/ #endif /*HAVE_JOLIET*/
@ -876,17 +900,10 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
/* Use the plain ISO-9660 name when dealing with a multiextent file part */ /* 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); strncpy(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
} }
if (p_stat->extents >= ISO_MAX_MULTIEXTENT) {
cdio_warn("Warning: Too many multiextent file parts for '%s'", p_stat->filename);
free(p_stat->rr.psz_symlink);
free(p_stat);
return NULL;
}
p_stat->extents++;
iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm)); iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm));
if (dir_len < sizeof (iso9660_dir_t)) { if (dir_len < sizeof(iso9660_dir_t)) {
iso9660_stat_free(p_stat); iso9660_stat_free(p_stat);
return NULL; return NULL;
} }
@ -932,6 +949,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
} }
return p_stat; return p_stat;
fail:
iso9660_stat_free(p_stat);
return NULL;
} }
/*! /*!
@ -1037,8 +1057,11 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
{ {
unsigned offset = 0; unsigned offset = 0;
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
uint32_t blocks;
iso9660_stat_t *p_stat; iso9660_stat_t *p_stat;
generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env; generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;
iso9660_stat_t *p_iso9660_stat = NULL;
bool skip_following_extents = false;
if (!splitpath[0]) if (!splitpath[0])
{ {
@ -1057,29 +1080,42 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
return NULL; return NULL;
cdio_assert (_root->type == _STAT_DIR); cdio_assert (_root->type == _STAT_DIR);
blocks = CDIO_EXTENT_BLOCKS(_root->total_size);
_dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE); _dirbuf = calloc(1, blocks * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", blocks * ISO_BLOCKSIZE);
return NULL; return NULL;
} }
if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn[0], ISO_BLOCKSIZE, if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn, ISO_BLOCKSIZE,
_root->secsize[0])) blocks))
return NULL; return NULL;
while (offset < (_root->secsize[0] * ISO_BLOCKSIZE)) while (offset < (blocks * 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;
int cmp; int cmp;
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue; continue;
p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, if (skip_following_extents) {
dunno, p_env->u_joliet_level); /* 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);
if (NULL == p_iso9660_stat)
skip_following_extents = true; /* Start ill file mode */
}
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
skip_following_extents = false; /* Ill or not: The file ends now */
if (NULL == p_iso9660_stat ||
(p_iso9660_dir->file_flags & ISO_MULTIEXTENT))
goto skip_to_next_record;
cmp = strcmp(splitpath[0], p_iso9660_stat->filename); cmp = strcmp(splitpath[0], p_iso9660_stat->filename);
@ -1093,7 +1129,7 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
if (!trans_fname) { if (!trans_fname) {
cdio_warn("can't allocate %lu bytes", cdio_warn("can't allocate %lu bytes",
(long unsigned int) strlen(p_iso9660_stat->filename)); (long unsigned int) strlen(p_iso9660_stat->filename));
free(p_iso9660_stat); iso9660_stat_free(p_iso9660_stat);
return NULL; return NULL;
} }
iso9660_name_translate_ext(p_iso9660_stat->filename, trans_fname, iso9660_name_translate_ext(p_iso9660_stat->filename, trans_fname,
@ -1112,11 +1148,14 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root,
} }
iso9660_stat_free(p_iso9660_stat); iso9660_stat_free(p_iso9660_stat);
p_iso9660_stat = NULL;
skip_to_next_record:;
offset += iso9660_get_dir_len(p_iso9660_dir); offset += iso9660_get_dir_len(p_iso9660_dir);
} }
cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE)); cdio_assert (offset == (blocks * ISO_BLOCKSIZE));
/* not found */ /* not found */
free (_dirbuf); free (_dirbuf);
@ -1129,6 +1168,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;
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;
@ -1151,20 +1191,21 @@ _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[0] * ISO_BLOCKSIZE); blocks = CDIO_EXTENT_BLOCKS(_root->total_size);
_dirbuf = calloc(1, blocks * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", blocks * ISO_BLOCKSIZE);
return NULL; return NULL;
} }
ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]); ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, blocks);
if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) { if (ret != blocks * ISO_BLOCKSIZE) {
free(_dirbuf); free(_dirbuf);
return NULL; return NULL;
} }
for (offset = 0; offset < (_root->secsize[0] * ISO_BLOCKSIZE); for (offset = 0; offset < (blocks * ISO_BLOCKSIZE);
offset += iso9660_get_dir_len(p_iso9660_dir)) offset += iso9660_get_dir_len(p_iso9660_dir))
{ {
p_iso9660_dir = (void *) &_dirbuf[offset]; p_iso9660_dir = (void *) &_dirbuf[offset];
@ -1197,7 +1238,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
if (!trans_fname) { if (!trans_fname) {
cdio_warn("can't allocate %lu bytes", cdio_warn("can't allocate %lu bytes",
(long unsigned int) strlen(p_stat->filename)); (long unsigned int) strlen(p_stat->filename));
free(p_stat); iso9660_stat_free(p_stat);
return NULL; return NULL;
} }
iso9660_name_translate_ext(p_stat->filename, trans_fname, iso9660_name_translate_ext(p_stat->filename, trans_fname,
@ -1218,7 +1259,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
p_stat = NULL; p_stat = NULL;
} }
cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE)); cdio_assert (offset == (blocks * ISO_BLOCKSIZE));
/* not found */ /* not found */
free (_dirbuf); free (_dirbuf);
@ -1259,7 +1300,7 @@ iso9660_fs_stat (CdIo_t *p_cdio, const char psz_path[])
p_psz_splitpath = _cdio_strsplit (psz_path, '/'); p_psz_splitpath = _cdio_strsplit (psz_path, '/');
p_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath); p_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath);
free(p_root); iso9660_stat_free(p_root);
_cdio_strfreev (p_psz_splitpath); _cdio_strfreev (p_psz_splitpath);
return p_stat; return p_stat;
@ -1292,7 +1333,7 @@ fs_stat_translate (void *p_image, stat_root_t stat_root,
p_psz_splitpath = _cdio_strsplit (psz_path, '/'); p_psz_splitpath = _cdio_strsplit (psz_path, '/');
p_stat = stat_traverse (p_image, p_root, p_psz_splitpath); p_stat = stat_traverse (p_image, p_root, p_psz_splitpath);
free(p_root); iso9660_stat_free(p_root);
_cdio_strfreev (p_psz_splitpath); _cdio_strfreev (p_psz_splitpath);
return p_stat; return p_stat;
@ -1362,7 +1403,7 @@ iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[])
splitpath = _cdio_strsplit (psz_path, '/'); splitpath = _cdio_strsplit (psz_path, '/');
stat = _fs_iso_stat_traverse (p_iso, p_root, splitpath); stat = _fs_iso_stat_traverse (p_iso, p_root, splitpath);
free(p_root); iso9660_stat_free(p_root);
_cdio_strfreev (splitpath); _cdio_strfreev (splitpath);
return stat; return stat;
@ -1403,37 +1444,48 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
{ {
unsigned offset = 0; unsigned offset = 0;
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
uint32_t blocks = CDIO_EXTENT_BLOCKS(p_stat->total_size);
CdioISO9660DirList_t *retval = _cdio_list_new (); CdioISO9660DirList_t *retval = _cdio_list_new ();
bool skip_following_extents = false;
_dirbuf = calloc(1, p_stat->secsize[0] * ISO_BLOCKSIZE); _dirbuf = calloc(1, blocks * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", p_stat->secsize[0] * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", blocks * ISO_BLOCKSIZE);
iso9660_stat_free(p_stat); iso9660_stat_free(p_stat);
iso9660_dirlist_free(retval); iso9660_dirlist_free(retval);
return NULL; return NULL;
} }
if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn[0], if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn,
ISO_BLOCKSIZE, p_stat->secsize[0])) { ISO_BLOCKSIZE, blocks)) {
iso9660_stat_free(p_stat); iso9660_stat_free(p_stat);
iso9660_dirlist_free(retval); iso9660_dirlist_free(retval);
return NULL; return NULL;
} }
while (offset < (p_stat->secsize[0] * ISO_BLOCKSIZE)) while (offset < (blocks * ISO_BLOCKSIZE))
{ {
p_iso9660_dir = (void *) &_dirbuf[offset]; p_iso9660_dir = (void *) &_dirbuf[offset];
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue; continue;
if (skip_following_extents) {
/* 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 = _iso9660_dir_to_statbuf(p_iso9660_dir,
p_iso9660_stat, dunno, p_iso9660_stat, dunno,
p_env->u_joliet_level); p_env->u_joliet_level);
if (NULL == p_iso9660_stat)
skip_following_extents = true; /* Start ill file mode */
}
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
skip_following_extents = false; /* Ill or not: The file ends now */
if ((p_iso9660_stat) && if ((p_iso9660_stat) &&
((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)) ((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; p_iso9660_stat = NULL;
} }
@ -1441,7 +1493,7 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[])
offset += iso9660_get_dir_len(p_iso9660_dir); offset += iso9660_get_dir_len(p_iso9660_dir);
} }
cdio_assert (offset == (p_stat->secsize[0] * ISO_BLOCKSIZE)); cdio_assert (offset == (blocks * ISO_BLOCKSIZE));
free(_dirbuf); free(_dirbuf);
iso9660_stat_free(p_stat); iso9660_stat_free(p_stat);
@ -1475,13 +1527,14 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
long int ret; long int ret;
unsigned offset = 0; unsigned offset = 0;
uint8_t *_dirbuf = NULL; uint8_t *_dirbuf = NULL;
uint32_t blocks = CDIO_EXTENT_BLOCKS(p_stat->total_size);
CdioList_t *retval = _cdio_list_new (); CdioList_t *retval = _cdio_list_new ();
const size_t dirbuf_len = p_stat->secsize[0] * ISO_BLOCKSIZE; const size_t dirbuf_len = blocks * ISO_BLOCKSIZE;
bool skip_following_extents = false;
if (!dirbuf_len) if (!dirbuf_len)
{ {
cdio_warn("Invalid directory buffer sector size %u", p_stat->secsize[0]); cdio_warn("Invalid directory buffer sector size %u", blocks);
iso9660_stat_free(p_stat); iso9660_stat_free(p_stat);
_cdio_list_free (retval, true, NULL); _cdio_list_free (retval, true, NULL);
return NULL; return NULL;
@ -1496,7 +1549,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[0], p_stat->secsize[0]); ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn, blocks);
if (ret != dirbuf_len) { if (ret != dirbuf_len) {
_cdio_list_free (retval, true, NULL); _cdio_list_free (retval, true, NULL);
iso9660_stat_free(p_stat); iso9660_stat_free(p_stat);
@ -1511,13 +1564,21 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[])
if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) if (iso9660_check_dir_block_end(p_iso9660_dir, &offset))
continue; continue;
if (skip_following_extents) {
/* 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 = _iso9660_dir_to_statbuf(p_iso9660_dir,
p_iso9660_stat, p_iso9660_stat,
p_iso->b_xa, p_iso->b_xa,
p_iso->u_joliet_level); p_iso->u_joliet_level);
if (NULL == p_iso9660_stat)
skip_following_extents = true; /* Start ill file mode */
}
if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)
skip_following_extents = false; /* Ill or not: The file ends now */
if ((p_iso9660_stat) && if ((p_iso9660_stat) &&
((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)) ((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; p_iso9660_stat = NULL;
} }
@ -1568,7 +1629,6 @@ 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);
@ -1581,11 +1641,12 @@ 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));
} }
for (extent = 0; extent < statbuf->extents; extent++) { if (statbuf->lsn == lsn) {
if (statbuf->lsn[extent] == lsn) { const unsigned int len2 = sizeof(iso9660_stat_t) +
const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1; strlen(statbuf->filename) + 1;
iso9660_stat_t *ret_stat = calloc(1, len2); iso9660_stat_t *ret_stat = calloc(1, len2);
if (!ret_stat) { if (!ret_stat)
{
iso9660_dirlist_free(dirlist); iso9660_dirlist_free(dirlist);
cdio_warn("Couldn't calloc(1, %d)", len2); cdio_warn("Couldn't calloc(1, %d)", len2);
free(*ppsz_full_filename); free(*ppsz_full_filename);
@ -1597,7 +1658,6 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir,
iso9660_dirlist_free(dirlist); iso9660_dirlist_free(dirlist);
return ret_stat; return ret_stat;
} }
}
} }
@ -1766,6 +1826,7 @@ iso_have_rr_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;
int ret; int ret;
bool_3way_t have_rr = nope; bool_3way_t have_rr = nope;
@ -1776,20 +1837,21 @@ 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[0] * ISO_BLOCKSIZE); blocks = CDIO_EXTENT_BLOCKS(_root->total_size);
_dirbuf = calloc(1, blocks * ISO_BLOCKSIZE);
if (!_dirbuf) if (!_dirbuf)
{ {
cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE); cdio_warn("Couldn't calloc(1, %d)", blocks * ISO_BLOCKSIZE);
return dunno; return dunno;
} }
ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]); ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, blocks);
if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) { if (ret != blocks * ISO_BLOCKSIZE) {
free(_dirbuf); free(_dirbuf);
return false; return false;
} }
while (offset < (_root->secsize[0] * ISO_BLOCKSIZE)) while (offset < (blocks * 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;
@ -1808,7 +1870,7 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
have_rr = iso_have_rr_traverse (p_iso, p_stat, &splitpath[i_last_component], have_rr = iso_have_rr_traverse (p_iso, p_stat, &splitpath[i_last_component],
pu_file_limit); pu_file_limit);
} }
free(p_stat); iso9660_stat_free(p_stat);
if (have_rr != nope) { if (have_rr != nope) {
free (_dirbuf); free (_dirbuf);
return have_rr; return have_rr;
@ -1822,7 +1884,7 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root,
} }
} }
cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE)); cdio_assert (offset == (blocks * ISO_BLOCKSIZE));
/* not found */ /* not found */
free (_dirbuf); free (_dirbuf);
@ -1858,7 +1920,7 @@ iso9660_have_rr(iso9660_t *p_iso, uint64_t u_file_limit)
if (u_file_limit == 0) u_file_limit = UINT64_MAX; if (u_file_limit == 0) u_file_limit = UINT64_MAX;
is_rr = iso_have_rr_traverse (p_iso, p_root, p_psz_splitpath, &u_file_limit); is_rr = iso_have_rr_traverse (p_iso, p_root, p_psz_splitpath, &u_file_limit);
free(p_root); iso9660_stat_free(p_root);
free(p_psz_splitpath[0]); free(p_psz_splitpath[0]);
free(p_psz_splitpath[1]); free(p_psz_splitpath[1]);

View file

@ -422,7 +422,7 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir,
switch(p_sl->flags &~1){ switch(p_sl->flags &~1){
case 0: case 0:
realloc_symlink(p_stat, p_sl->len); realloc_symlink(p_stat, p_sl->len);
if (p_sl->text && p_sl->len) if (p_sl->len)
memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]), memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]),
p_sl->text, p_sl->len); p_sl->text, p_sl->len);
p_stat->rr.i_symlink += p_sl->len; p_stat->rr.i_symlink += p_sl->len;

View file

@ -133,12 +133,13 @@ udf_stamp_to_time(time_t *dest, long int *dest_usec,
return NULL; return NULL;
} }
*dest = year_seconds[src.year - EPOCH_YEAR]; *dest = year_seconds[src.year - EPOCH_YEAR];
*dest -= (time_t)offset * SECS_PER_MINUTE; *dest -= offset * SECS_PER_MINUTE;
yday = ((__mon_yday[__isleap (src.year)] yday = ((__mon_yday[__isleap (src.year)]
[src.month-1]) + (src.day-1)); [src.month-1]) + (src.day-1));
*dest += (time_t)src.second + ((time_t)SECS_PER_MINUTE * *dest += src.second +
( ( ((time_t)yday* HOURS_PER_DAY) + src.hour ) * 60 + src.minute ) ); ( SECS_PER_MINUTE *
( ( (yday* HOURS_PER_DAY) + src.hour ) * 60 + src.minute ) );
*dest_usec = src.microseconds *dest_usec = src.microseconds
+ (src.centiseconds * 10000) + (src.centiseconds * 10000)

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 3.10.1656" CAPTION "Rufus 3.10.1657"
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
@ -395,8 +395,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,10,1656,0 FILEVERSION 3,10,1657,0
PRODUCTVERSION 3,10,1656,0 PRODUCTVERSION 3,10,1657,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -414,13 +414,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", "3.10.1656" VALUE "FileVersion", "3.10.1657"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalCopyright", "© 2011-2020 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-3.10.exe" VALUE "OriginalFilename", "rufus-3.10.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "3.10.1656" VALUE "ProductVersion", "3.10.1657"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"