diff --git a/src/iso.c b/src/iso.c index b2e9abe2..0cb93a91 100644 --- a/src/iso.c +++ b/src/iso.c @@ -36,6 +36,7 @@ #include #include +#define DO_NOT_WANT_COMPATIBILITY #include #include #include @@ -630,9 +631,9 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) CdioListNode_t* p_entnode; iso9660_stat_t *p_statbuf; CdioISO9660FileList_t* p_entlist; - size_t i, j; + size_t i; lsn_t lsn; - int64_t file_length, extent_length; + int64_t file_length; if ((p_iso == NULL) || (psz_path == NULL)) 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)) goto out; } 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)) { continue; } @@ -721,29 +722,24 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) uprintf(stupid_antivirus); else goto out; - } else { - for (j=0; jextents; j++) { - extent_length = p_statbuf->extsize[j]; - for (i=0; extent_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(extent_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; - } - extent_length -= ISO_BLOCKSIZE; - if (nb_blocks++ % PROGRESS_THRESHOLD == 0) - UpdateProgressWithInfo(OP_FILE_COPY, MSG_231, nb_blocks, total_blocks); - } + } else for (i = 0; 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(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; + } + file_length -= ISO_BLOCKSIZE; + if (nb_blocks++ % PROGRESS_THRESHOLD == 0) + UpdateProgressWithInfo(OP_FILE_COPY, MSG_231, nb_blocks, total_blocks); } if (preserve_timestamps) { LPFILETIME ft = to_filetime(mktime(&p_statbuf->tm)); @@ -1091,9 +1087,9 @@ out: 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; - int64_t file_length, extent_length, r = 0; + int64_t file_length, r = 0; char buf[UDF_BLOCKSIZE]; DWORD buf_size, wr_size; iso9660_t* p_iso = NULL; @@ -1156,23 +1152,21 @@ try_iso: goto out; } - for (j = 0; j < p_statbuf->extents; j++) { - extent_length = p_statbuf->extsize[j]; - for (i = 0; extent_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(extent_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; - } - extent_length -= ISO_BLOCKSIZE; - r += ISO_BLOCKSIZE; + file_length = p_statbuf->total_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; + } + file_length -= ISO_BLOCKSIZE; + r += ISO_BLOCKSIZE; } out: @@ -1241,8 +1235,8 @@ try_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[0], 1) != ISO_BLOCKSIZE) { - uprintf("Error reading ISO-9660 file %s at LSN %d", wim_path, p_statbuf->lsn[0]); + 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); goto out; } r = wim_header[3]; @@ -1332,7 +1326,7 @@ BOOL HasEfiImgBootLoaders(void) if (p_private == NULL) goto out; 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; // 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) { @@ -1424,7 +1418,7 @@ BOOL DumpFatDir(const char* path, int32_t cluster) if (p_private == NULL) goto out; 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; // 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) { diff --git a/src/libcdio/cdio/audio.h b/src/libcdio/cdio/audio.h index 099a1236..1cf1394b 100644 --- a/src/libcdio/cdio/audio.h +++ b/src/libcdio/cdio/audio.h @@ -1,5 +1,5 @@ /* -*- c -*- - Copyright (C) 2005, 2007, 2008 Rocky Bernstein + Copyright (C) 2005, 2007, 2008, 2019 Rocky Bernstein 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 @@ -15,10 +15,10 @@ along with this program. If not, see . */ -/** \file audio.h +/** \file audio.h * * \brief The top-level header for CD audio-related libcdio - * calls. These control playing of the CD-ROM through its + * calls. These control playing of the CD-ROM through its * line-out jack. */ #ifndef CDIO_AUDIO_H_ @@ -31,7 +31,7 @@ extern "C" { #endif /* __cplusplus */ /*! This struct is used by the cdio_audio_read_subchannel */ - typedef struct cdio_subchannel_s + typedef struct cdio_subchannel_s { uint8_t format; uint8_t audio_status; @@ -42,13 +42,13 @@ extern "C" { msf_t abs_addr; msf_t rel_addr; } cdio_subchannel_t; - + /*! This struct is used by cdio_audio_get_volume and cdio_audio_set_volume */ typedef struct cdio_audio_volume_s { uint8_t level[4]; } cdio_audio_volume_t; - + /*! This struct is used by the CDROMPLAYTRKIND ioctl */ typedef struct cdio_track_index_s @@ -61,19 +61,19 @@ extern "C" { /*! Get volume of an audio CD. - + @param p_cdio the CD object to be acted upon. @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 - has the ability to get the volume or not. + \p p_volume can be \p NULL in which case we return only whether + the driver has the ability to get the volume or not. */ driver_return_code_t cdio_audio_get_volume (CdIo_t *p_cdio, /*out*/ cdio_audio_volume_t *p_volume); - /*! - Return the number of seconds (discarding frame portion) of an MSF + /*! + Return the number of seconds (discarding frame portion) of an MSF */ uint32_t cdio_audio_get_msf_seconds(msf_t *p_msf); @@ -91,7 +91,7 @@ extern "C" { @param p_start_msf pointer to staring MSF @param p_end_msf pointer to ending MSF */ - driver_return_code_t cdio_audio_play_msf (CdIo_t *p_cdio, + driver_return_code_t cdio_audio_play_msf (CdIo_t *p_cdio, /*in*/msf_t *p_start_msf, /*in*/ msf_t *p_end_msf); @@ -101,7 +101,7 @@ extern "C" { @param p_cdio the CD object to be acted upon. @param p_track_index location to start/end. */ - driver_return_code_t cdio_audio_play_track_index + driver_return_code_t cdio_audio_play_track_index ( CdIo_t *p_cdio, cdio_track_index_t *p_track_index); /*! @@ -110,12 +110,12 @@ extern "C" { @param p_cdio the CD object to be acted upon. @param p_subchannel place for returned subchannel information */ - driver_return_code_t cdio_audio_read_subchannel (CdIo_t *p_cdio, + driver_return_code_t cdio_audio_read_subchannel (CdIo_t *p_cdio, /*out*/ cdio_subchannel_t *p_subchannel); /*! Resume playing an audio CD. - + @param p_cdio the CD object to be acted upon. */ @@ -123,7 +123,7 @@ extern "C" { /*! Set volume of an audio CD. - + @param p_cdio the CD object to be acted upon. @param p_volume place for returned volume-level information @@ -133,7 +133,7 @@ extern "C" { /*! Stop playing an audio CD. - + @param p_cdio the CD object to be acted upon. */ diff --git a/src/libcdio/cdio/cdio.h b/src/libcdio/cdio/cdio.h index 572cf4ab..7f095bbc 100644 --- a/src/libcdio/cdio/cdio.h +++ b/src/libcdio/cdio/cdio.h @@ -17,7 +17,7 @@ along with this program. If not, see . */ -/** \file cdio.h +/** \file cdio.h * * \brief The top-level header for libcdio: the CD Input and Control * library. Applications include this for anything regarding libcdio. @@ -42,15 +42,15 @@ extern "C" { /* For compatibility. */ #define CdIo CdIo_t - + /** This is an opaque structure for the CD object. */ - typedef struct _CdIo CdIo_t; + typedef struct _CdIo CdIo_t; #ifdef __cplusplus } #endif /* __cplusplus */ -/* Drive(r)/Device-related functions. Perhaps we should break out +/* Drive(r)/Device-related functions. Perhaps we should break out Driver from device? */ #include @@ -62,7 +62,7 @@ extern "C" { #include /* Sector (frame, or block)-related functions. Uses driver_return_code_t - from so it should come after that. + from so it should come after that. */ #include diff --git a/src/libcdio/cdio/cdtext.h b/src/libcdio/cdio/cdtext.h index 32eb9115..eb7db8c4 100644 --- a/src/libcdio/cdio/cdtext.h +++ b/src/libcdio/cdio/cdtext.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004, 2005, 2008, 2012 Rocky Bernstein + Copyright (C) 2018 Thomas Schmitt + Copyright (C) 2004, 2005, 2008, 2012, 2019 Rocky Bernstein adapted from cuetools Copyright (C) 2003 Svend Sanjay Sorensen @@ -17,7 +18,7 @@ along with this program. If not, see . */ /*! - * \file cdtext.h + * \file cdtext.h * * \brief The top-level header for CD-Text information. Applications * include this for CD-Text access. @@ -36,7 +37,10 @@ extern "C" { #define MIN_CDTEXT_FIELD 0 #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 { CDTEXT_FIELD_TITLE = 0, /**< title of album name or track titles */ 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_t; -/*! Enumeration of possible genre codes. */ +/*! \typedef enum cdtext_genre_t + + \brief Enumeration of possible genre codes. +*/ typedef enum { CDTEXT_GENRE_UNUSED = 0, /**< field is not used. default */ CDTEXT_GENRE_UNDEFINED = 1, /**< not defined */ @@ -84,10 +91,12 @@ typedef enum { CDTEXT_GENRE_WORLD_MUSIC = 28 /**< World Music */ } cdtext_genre_t; -/*! Enumeration of possible CD-TEXT languages. - * - * The language code is encoded as specified in ANNEX 1 to part 5 of EBU - * Tech 32 58 -E (1991). +/*! \typedef typedef enum cdtext_lang_t + + \brief Enumeration of possible CD-TEXT languages. + + The language code is encoded as specified in ANNEX 1 to part 5 of EBU + Tech 32 58 -E (1991). */ typedef enum { CDTEXT_LANGUAGE_UNKNOWN = 0x00, @@ -192,11 +201,19 @@ typedef enum { CDTEXT_LANGUAGE_ASSAMESE = 0x7C, CDTEXT_LANGUAGE_ARMENIAN = 0x7D, 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; /*! - Opaque type for CD-Text. + \typedef struct cdtext_s cdtext_t + + \brief Opaque type for CD-Text. */ typedef struct cdtext_s cdtext_t; @@ -210,34 +227,69 @@ const char *cdtext_genre2str (cdtext_genre_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. */ 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. */ 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 + 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 wdata the data @param i_data size of wdata @returns 0 on success, non-zero on failure -*/ +*/ 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 */ void cdtext_destroy (cdtext_t *p_cdtext); @@ -259,7 +311,7 @@ char *cdtext_get (const cdtext_t *p_cdtext, cdtext_field_t key, track_t track); @param field type of the field to return @param track specifies the track, 0 stands for disc */ -const char *cdtext_get_const (const cdtext_t *p_cdtext, cdtext_field_t field, +const char *cdtext_get_const (const cdtext_t *p_cdtext, cdtext_field_t field, track_t track); /*! @@ -300,20 +352,66 @@ track_t cdtext_get_last_track(const cdtext_t *p_cdtext); */ 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. + __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. @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); -/*! +/*! + 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. - - 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 key field to set @param value value to set @@ -328,7 +426,7 @@ void cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, t #endif /* CDIO_CDTEXT_H_ */ -/* +/* * Local variables: * c-file-style: "gnu" * tab-width: 8 diff --git a/src/libcdio/cdio/device.h b/src/libcdio/cdio/device.h index 8917479b..af8d4105 100644 --- a/src/libcdio/cdio/device.h +++ b/src/libcdio/cdio/device.h @@ -109,7 +109,7 @@ extern "C" { /**< Has some sort of DVD or CD writing ability */ } cdio_drive_cap_write_t; -/** Size of fields returned by an INQUIRY command */ +/** Size of fields returned by an \p INQUIRY command */ typedef enum { CDIO_MMC_HW_VENDOR_LEN = 8, /**< length of vendor 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 - strings obtained via the INQUIRY command */ + strings obtained via the \p INQUIRY command */ typedef struct cdio_hwinfo { 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 use the default device. + @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. */ 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. - @return the string information about drc + + @return the string information about \p 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. @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); @@ -266,23 +268,24 @@ extern "C" { /** 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 - 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[]); /** 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. @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. 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. - 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. - 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); /** Return an array of device names. If you want a specific devices for a driver, give that device. If you want hardware - devices, give DRIVER_DEVICE and if you want all possible devices, - image drivers and hardware drivers give DRIVER_UNKNOWN. + devices, give \p DRIVER_DEVICE and if you want all possible devices, + image drivers and hardware drivers give \p DRIVER_UNKNOWN. 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 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); /** Get an array of device names in search_devices that have at least 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 "analysis" part. @@ -353,7 +356,7 @@ extern "C" { 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 and then *open* it afterwards. Giving the driver back facilitates this, and speeds things up for libcdio as well. @@ -364,8 +367,8 @@ extern "C" { /*out*/ driver_id_t *p_driver_id); /** - 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 + Like cdio_get_devices(), but we may change the p_driver_id if we + were given \p DRIVER_DEVICE or \p DRIVER_UNKNOWN. This is because often one wants to get a drive name and then *open* it afterwards. Giving the driver back facilitates this, and speeds 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 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, 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 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, 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. + @param p_cdio the CD object to be acted upon. + @return a string with driver name or NULL if CdIo_t is NULL (we haven't initialized a specific device. */ 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. - if CdIo is NULL (we haven't initialized a specific device driver), - then return NULL. + Return a string name for the \p driver_id. */ const char * cdio_get_driver_name_from_id (driver_id_t driver_id); /** Get the driver id. - if CdIo_t is NULL (we haven't initialized a specific device driver), - then return DRIVER_UNKNOWN. + if \p p_cdio is \p NULL (we haven't initialized a specific device driver), + then return \p DRIVER_UNKNOWN. + + @param p_cdio the CD object to be acted upon. @return the driver id.. */ @@ -449,9 +454,11 @@ extern "C" { /** Find out if media has changed since the last call. + @param p_cdio the CD object to be acted upon. + @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); @@ -462,7 +469,7 @@ extern "C" { 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. @param p_cdio the CD object to eliminated. @@ -478,8 +485,8 @@ extern "C" { const char *cdio_driver_describe (driver_id_t driver_id); /** - Sets up to read from place specified by psz_source and - driver_id. This or cdio_open_* should be called before using any + Sets up to read from place specified by \p psz_source and + \p driver_id. This or cdio_open_* should be called before using any other routine, except cdio_init or any routine that accesses the CD-ROM drive by name. cdio_open will call cdio_init, if that 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 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, 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 .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); @@ -515,7 +523,7 @@ extern "C" { Set up BIN/CUE CD disk-image for reading. Source is the .bin or .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, const char *psz_access_mode); @@ -523,7 +531,7 @@ extern "C" { /** 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); @@ -539,7 +547,7 @@ extern "C" { Return a string containing the default CUE file that would 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); @@ -547,7 +555,7 @@ extern "C" { /** @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. */ char * cdio_get_default_device_cdrdao(void); @@ -559,7 +567,7 @@ extern "C" { the some sort of device name. @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); @@ -568,7 +576,7 @@ extern "C" { the some sort of device name. @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, const char *psz_access_mode); @@ -577,7 +585,7 @@ extern "C" { CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file @return the cdio object for subsequent operations. - NULL on error. + \p NULL on error. */ CdIo_t * cdio_open_cue (const char *cue_name); @@ -586,9 +594,9 @@ extern "C" { the some sort of device name. @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, const char *psz_access_mode); @@ -598,9 +606,9 @@ extern "C" { the some sort of device name. @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); @@ -609,9 +617,9 @@ extern "C" { driver would use when none is specified. @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); @@ -621,62 +629,17 @@ extern "C" { 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. + return \p NULL even though there may be a hardware CD-ROM. */ 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 device_name is the some sort of device name. 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); @@ -686,7 +649,7 @@ extern "C" { 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, const char *psz_access_mode); @@ -754,7 +717,7 @@ extern "C" { device_name is the some sort of device name. @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); @@ -763,7 +726,7 @@ extern "C" { device_name is the some sort of device name. @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, const char *psz_access_mode); @@ -773,13 +736,13 @@ extern "C" { Solaris driver would use when none is specified. A scan is made 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 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); @@ -793,13 +756,13 @@ extern "C" { Set up CD-ROM for reading using the Apple OSX driver. The 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 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 + @see cdio_open_cd(), cdio_open() */ 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. - @see cdio_open_cd, cdio_open + @see cdio_open_cd(), cdio_open() */ CdIo_t * cdio_open_am_osx (const char *psz_source, 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 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_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 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. @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); @@ -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. @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); @@ -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 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, 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. - @param p_cdio the CD object queried - @param key the key to retrieve - @return the value associatd with "key" or NULL if p_cdio is NULL - or "key" does not exist. + @param p_cdio the CD object queried @param key the key to + retrieve @return the value associated with "key", \p NULL if \p + p_cdio is \p NULL, or "key" does not exist. */ const char * cdio_get_arg (const CdIo_t *p_cdio, const char key[]); diff --git a/src/libcdio/cdio/disc.h b/src/libcdio/cdio/disc.h index ef053fd0..e6933ebe 100644 --- a/src/libcdio/cdio/disc.h +++ b/src/libcdio/cdio/disc.h @@ -1,5 +1,6 @@ /* -*- c -*- + Copyright (C) 2018 Thomas Schmitt Copyright (C) 2004, 2005, 2006, 2008, 2010, 2012, 2014 Rocky Bernstein @@ -18,7 +19,7 @@ */ /** - \file disc.h + \file disc.h \brief The top-level header for disc-related libcdio calls. */ #ifndef CDIO_DISC_H_ @@ -58,25 +59,32 @@ extern "C" { 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 . + @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 - NULL if p_cdio is NULL or CD-Text information does not exist. Return - value must be freed with cdio_free() when done with it and not NULL. + @return malloc'd pointer to raw CD-Text data as replied by the drive + or NULL if problems occur or CD-Text information does not exist. + A non-NULL return value must be freed with cdio_free() when done. */ 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 . + @param p_cdio the CD object that may contain CD-Text information. - @return the CD-Text object or NULL if p_cdio is NULL - or CD-Text information does not exist. + @return a pointer to the attached cdtext_t object or NULL if problems + occur or if CD-Text information does not exist. */ cdtext_t *cdio_get_cdtext (CdIo_t *p_cdio); - /** + /** Get disc mode - the kind of CD (CD-DA, CD-ROM mode 1, CD-MIXED, etc. that we've got. The notion of "CD" is extended a little to include DVD's. @@ -89,7 +97,7 @@ extern "C" { @return the lsn. On error 0 or CDIO_INVALD_LSN. */ lsn_t cdio_get_disc_last_lsn(const CdIo_t *p_cdio); - + /** Return the Joliet level recognized for p_cdio. */ @@ -114,19 +122,19 @@ extern "C" { an error. */ track_t cdio_get_num_tracks (const CdIo_t *p_cdio); - + /** Return true if discmode is some sort of CD. */ bool cdio_is_discmode_cdrom (discmode_t discmode); - + /** Return true if discmode is some sort of DVD. */ bool cdio_is_discmode_dvd (discmode_t discmode); - + /** - cdio_stat_size is deprecated. @see cdio_get_disc_last_lsn + cdio_stat_size is deprecated. @see cdio_get_disc_last_lsn */ #define cdio_stat_size cdio_get_disc_last_lsn diff --git a/src/libcdio/cdio/iso9660.h b/src/libcdio/cdio/iso9660.h index 9925ed76..04308909 100644 --- a/src/libcdio/cdio/iso9660.h +++ b/src/libcdio/cdio/iso9660.h @@ -156,9 +156,6 @@ 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. */ @@ -166,6 +163,8 @@ extern const char ISO_STANDARD_ID[sizeof("CD001")-1]; #define ISO_STANDARD_ID "CD001" +#define CDIO_EXTENT_BLOCKS(size) ((size + (ISO_BLOCKSIZE - 1)) / ISO_BLOCKSIZE) + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -536,14 +535,33 @@ struct iso9660_stat_s { /* big endian!! */ struct tm tm; /**< time on entry - FIXME merge with one of entries above, like ctime? */ - uint64_t size; /**< total size in bytes */ - uint8_t extents; /**< number of multiextents */ - /**⌵ start logical sector number for each extent */ - lsn_t lsn[ISO_MAX_MULTIEXTENT]; - /**⌵ size of each extent */ - uint32_t extsize[ISO_MAX_MULTIEXTENT]; - /**⌵ number of sectors allocated for each extent */ - uint32_t secsize[ISO_MAX_MULTIEXTENT]; + lsn_t lsn; /**< start logical sector number */ + +#ifndef DO_NOT_WANT_COMPATIBILITY + + /* *** Deprecated Legacy API *** + Use .total_size and CDIO_EXTENT_BLOCKS. + */ + 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 */ enum { _STAT_FILE = 1, _STAT_DIR = 2 } type; bool b_xa; diff --git a/src/libcdio/cdio/types.h b/src/libcdio/cdio/types.h index dc7e4780..dc0f90cf 100644 --- a/src/libcdio/cdio/types.h +++ b/src/libcdio/cdio/types.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2012, 2017 + Copyright (C) 2002-2008, 2012, 2017 2019 Rocky Bernstein Copyright (C) 2000 Herbert Valerio Riedel @@ -27,6 +27,8 @@ #ifdef __cplusplus extern "C" { +#else +# include #endif /* __cplusplus */ /* If is not available on your platform please @@ -103,27 +105,6 @@ typedef uint8_t ubyte; # 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+ */ #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) @@ -151,7 +132,7 @@ typedef uint8_t ubyte; #define GNUC_PACKED #endif /* !__GNUC__ */ -#if defined(__MINGW32__) +#if defined(__MINGW32__) || (defined( __clang_major__) && __clang_major__ > 9) # define PRAGMA_BEGIN_PACKED _Pragma("pack(push)") \ _Pragma("pack(1)") # define PRAGMA_END_PACKED _Pragma("pack(pop)") diff --git a/src/libcdio/cdio/version.h b/src/libcdio/cdio/version.h index e18b2a40..fd72ae05 100644 --- a/src/libcdio/cdio/version.h +++ b/src/libcdio/cdio/version.h @@ -7,7 +7,7 @@ /*! 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 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 */ /*! LIBCDIO_VERSION_NUM is a C-Preprocessor macro that can be used for diff --git a/src/libcdio/cdio/xa.h b/src/libcdio/cdio/xa.h index 32e9f5ec..c9e091f0 100644 --- a/src/libcdio/cdio/xa.h +++ b/src/libcdio/cdio/xa.h @@ -71,7 +71,9 @@ extern "C" { XA_FORM2_FILE = (XA_ATTR_MODE2FORM2 | XA_PERM_ALL_ALL) } 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. diff --git a/src/libcdio/config.h b/src/libcdio/config.h index 97675cd5..b0ee3c99 100644 --- a/src/libcdio/config.h +++ b/src/libcdio/config.h @@ -48,6 +48,9 @@ /* Define if you have the iconv() function and it works. */ /* #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 header file. */ #define HAVE_INTTYPES_H 1 /* provided in MSVC/missing if needed */ diff --git a/src/libcdio/driver/read.c b/src/libcdio/driver/read.c index 70f1ef19..ae15c39d 100644 --- a/src/libcdio/driver/read.c +++ b/src/libcdio/driver/read.c @@ -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); } else if (p_cdio->op.lseek && p_cdio->op.read) { 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; if (0 > cdio_read(p_cdio, buf, CDIO_CD_FRAMESIZE)) return -1; diff --git a/src/libcdio/iso9660/iso9660.c b/src/libcdio/iso9660/iso9660.c index 689aa5bb..ae4edda3 100644 --- a/src/libcdio/iso9660/iso9660.c +++ b/src/libcdio/iso9660/iso9660.c @@ -373,6 +373,9 @@ iso9660_set_ltime_with_timezone(const struct tm *p_tm, if (!p_tm) return; +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wformat-truncation" +#endif snprintf(_pvd_date, 17, "%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, @@ -632,7 +635,8 @@ iso9660_set_pvd(void *pd, memset(&ipd,0,sizeof(ipd)); /* paranoia? */ /* 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); iso9660_strncpy_pad (ipd.id, ISO_STANDARD_ID, 5, ISO9660_DCHARS); diff --git a/src/libcdio/iso9660/iso9660_fs.c b/src/libcdio/iso9660/iso9660_fs.c index f2e17107..0e8994b1 100644 --- a/src/libcdio/iso9660/iso9660_fs.c +++ b/src/libcdio/iso9660/iso9660_fs.c @@ -1,5 +1,7 @@ /* Copyright (C) 2003-2008, 2011-2015, 2017 Rocky Bernstein + Copyright (C) 2018, 2020 Pete Batard + Copyright (C) 2018 Thomas Schmitt Copyright (C) 2001 Herbert Valerio Riedel This program is free software: you can redistribute it and/or modify @@ -788,41 +790,67 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, unsigned int stat_len; iso9660_stat_t *p_stat = last_p_stat; char rr_fname[256] = ""; - int i_rr_fname; + int i_rr_fname; + lsn_t extent_lsn; + bool first_extent; 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' */ - 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 */ - if (!p_stat) - p_stat = calloc(1, stat_len); - if (!p_stat) - { + if (!p_stat) { + p_stat = calloc(1, stat_len); + first_extent = true; + } else { + first_extent = false; + } + if (!p_stat) { cdio_warn("Couldn't calloc(1, %d)", stat_len); return NULL; - } + } p_stat->type = (p_iso9660_dir->file_flags & ISO_DIRECTORY) ? _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); - p_stat->size += p_stat->extsize[p_stat->extents]; - p_stat->secsize[p_stat->extents] = _cdio_len2blocks (p_stat->extsize[p_stat->extents], ISO_BLOCKSIZE); + + /* Test for gaps between extents. Important: Use previous .total_size */ + extent_lsn = from_733 (p_iso9660_dir->extent); + 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->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 */ if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0) { /* Check if this is the last part of a multiextent file */ - if (p_stat->extents != 0) { - 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; + if (!first_extent) { + if (strlen(p_stat->filename) != i_fname || + strncmp(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname) != 0) { + cdio_warn("Non consecutive multiextent file parts for '%s'", + p_stat->filename); + goto fail; } } i_rr_fname = @@ -837,12 +865,10 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, /* realloc gives valgrind errors */ iso9660_stat_t *p_stat_new = calloc(1, sizeof(iso9660_stat_t)+i_rr_fname+2); - if (!p_stat_new) - { - cdio_warn("Couldn't calloc(1, %d)", (int)(sizeof(iso9660_stat_t)+i_rr_fname+2)); - free(p_stat); - return NULL; - } + if (!p_stat_new) { + cdio_warn("Couldn't calloc(1, %d)", (int)(sizeof(iso9660_stat_t)+i_rr_fname+2)); + goto fail; + } memcpy(p_stat_new, p_stat, stat_len); free(p_stat); p_stat = p_stat_new; @@ -850,9 +876,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, strncpy(p_stat->filename, rr_fname, i_rr_fname+1); } else { 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) - strncpy (p_stat->filename, "..", 3); + strncpy (p_stat->filename, "..", strlen("..")+1); #ifdef HAVE_JOLIET else if (u_joliet_level) { int i_inlen = i_fname; @@ -861,10 +887,8 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, &p_psz_out, "UCS-2BE")) { strncpy(p_stat->filename, p_psz_out, i_fname); free(p_psz_out); - } - else { - free(p_stat); - return NULL; + } else { + goto fail; } } #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 */ 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)); - if (dir_len < sizeof (iso9660_dir_t)) { + if (dir_len < sizeof(iso9660_dir_t)) { iso9660_stat_free(p_stat); return NULL; } @@ -932,6 +949,9 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, } 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; uint8_t *_dirbuf = NULL; + uint32_t blocks; iso9660_stat_t *p_stat; 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]) { @@ -1057,29 +1080,42 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root, return NULL; 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) { - cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE); + cdio_warn("Couldn't calloc(1, %d)", blocks * ISO_BLOCKSIZE); return NULL; } - if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn[0], ISO_BLOCKSIZE, - _root->secsize[0])) + if (cdio_read_data_sectors (p_cdio, _dirbuf, _root->lsn, ISO_BLOCKSIZE, + blocks)) return NULL; - while (offset < (_root->secsize[0] * ISO_BLOCKSIZE)) + while (offset < (blocks * ISO_BLOCKSIZE)) { iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; - iso9660_stat_t *p_iso9660_stat; int cmp; if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) continue; - p_iso9660_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, - dunno, p_env->u_joliet_level); + 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, 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); @@ -1093,7 +1129,7 @@ _fs_stat_traverse (const CdIo_t *p_cdio, const iso9660_stat_t *_root, if (!trans_fname) { cdio_warn("can't allocate %lu bytes", (long unsigned int) strlen(p_iso9660_stat->filename)); - free(p_iso9660_stat); + iso9660_stat_free(p_iso9660_stat); return NULL; } 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); + p_iso9660_stat = NULL; + +skip_to_next_record:; offset += iso9660_get_dir_len(p_iso9660_dir); } - cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE)); + cdio_assert (offset == (blocks * ISO_BLOCKSIZE)); /* not found */ free (_dirbuf); @@ -1129,6 +1168,7 @@ _fs_iso_stat_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, { unsigned offset = 0; uint8_t *_dirbuf = NULL; + uint32_t blocks; int ret, cmp; iso9660_stat_t *p_stat = 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); - _dirbuf = calloc(1, _root->secsize[0] * ISO_BLOCKSIZE); + blocks = CDIO_EXTENT_BLOCKS(_root->total_size); + _dirbuf = calloc(1, blocks * ISO_BLOCKSIZE); 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; } - ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]); - if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) { + ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, blocks); + if (ret != blocks * ISO_BLOCKSIZE) { free(_dirbuf); 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)) { 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) { cdio_warn("can't allocate %lu bytes", (long unsigned int) strlen(p_stat->filename)); - free(p_stat); + iso9660_stat_free(p_stat); return NULL; } 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; } - cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE)); + cdio_assert (offset == (blocks * ISO_BLOCKSIZE)); /* not found */ 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_stat = _fs_stat_traverse (p_cdio, p_root, p_psz_splitpath); - free(p_root); + iso9660_stat_free(p_root); _cdio_strfreev (p_psz_splitpath); 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_stat = stat_traverse (p_image, p_root, p_psz_splitpath); - free(p_root); + iso9660_stat_free(p_root); _cdio_strfreev (p_psz_splitpath); return p_stat; @@ -1362,7 +1403,7 @@ iso9660_ifs_stat (iso9660_t *p_iso, const char psz_path[]) splitpath = _cdio_strsplit (psz_path, '/'); stat = _fs_iso_stat_traverse (p_iso, p_root, splitpath); - free(p_root); + iso9660_stat_free(p_root); _cdio_strfreev (splitpath); return stat; @@ -1403,45 +1444,56 @@ iso9660_fs_readdir (CdIo_t *p_cdio, const char psz_path[]) { unsigned offset = 0; uint8_t *_dirbuf = NULL; + uint32_t blocks = CDIO_EXTENT_BLOCKS(p_stat->total_size); 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) { - 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_dirlist_free(retval); return NULL; } - if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn[0], - ISO_BLOCKSIZE, p_stat->secsize[0])) { + if (cdio_read_data_sectors (p_cdio, _dirbuf, p_stat->lsn, + ISO_BLOCKSIZE, blocks)) { iso9660_stat_free(p_stat); iso9660_dirlist_free(retval); return NULL; } - while (offset < (p_stat->secsize[0] * ISO_BLOCKSIZE)) + while (offset < (blocks * ISO_BLOCKSIZE)) { p_iso9660_dir = (void *) &_dirbuf[offset]; if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) continue; - p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, - p_iso9660_stat, dunno, - p_env->u_joliet_level); + 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, 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 ((p_iso9660_stat) && - ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)) - { - _cdio_list_append (retval, p_iso9660_stat); - p_iso9660_stat = NULL; - } + ((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); } - cdio_assert (offset == (p_stat->secsize[0] * ISO_BLOCKSIZE)); + cdio_assert (offset == (blocks * ISO_BLOCKSIZE)); free(_dirbuf); iso9660_stat_free(p_stat); @@ -1475,13 +1527,14 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) long int ret; unsigned offset = 0; uint8_t *_dirbuf = NULL; + uint32_t blocks = CDIO_EXTENT_BLOCKS(p_stat->total_size); 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) { - 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); _cdio_list_free (retval, true, NULL); return NULL; @@ -1496,7 +1549,7 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) 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) { _cdio_list_free (retval, true, NULL); iso9660_stat_free(p_stat); @@ -1511,16 +1564,24 @@ iso9660_ifs_readdir (iso9660_t *p_iso, const char psz_path[]) if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) continue; - p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, - p_iso9660_stat, - p_iso->b_xa, - p_iso->u_joliet_level); + 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, + p_iso->b_xa, + 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) && - ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0)) - { - _cdio_list_append(retval, p_iso9660_stat); - p_iso9660_stat = NULL; - } + ((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); } @@ -1568,7 +1629,6 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir, iso9660_stat_t *statbuf = _cdio_list_node_data (entnode); const char *psz_filename = (char *) statbuf->filename; unsigned int len = strlen(psz_path) + strlen(psz_filename)+2; - size_t extent; if (*ppsz_full_filename != NULL) free(*ppsz_full_filename); *ppsz_full_filename = calloc(1, len); @@ -1577,26 +1637,26 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir, if (statbuf->type == _STAT_DIR && strcmp ((char *) statbuf->filename, ".") && strcmp ((char *) statbuf->filename, "..")) { - snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename); + snprintf (*ppsz_full_filename, len, "%s%s/", psz_path, psz_filename); _cdio_list_append (dirlist, strdup(*ppsz_full_filename)); } - for (extent = 0; extent < statbuf->extents; extent++) { - if (statbuf->lsn[extent] == lsn) { - const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1; - iso9660_stat_t *ret_stat = calloc(1, len2); - if (!ret_stat) { - iso9660_dirlist_free(dirlist); - cdio_warn("Couldn't calloc(1, %d)", len2); - free(*ppsz_full_filename); - *ppsz_full_filename = NULL; - return NULL; - } - memcpy(ret_stat, statbuf, len2); - iso9660_filelist_free (entlist); - iso9660_dirlist_free(dirlist); - return ret_stat; - } + if (statbuf->lsn == lsn) { + const unsigned int len2 = sizeof(iso9660_stat_t) + + strlen(statbuf->filename) + 1; + iso9660_stat_t *ret_stat = calloc(1, len2); + if (!ret_stat) + { + iso9660_dirlist_free(dirlist); + cdio_warn("Couldn't calloc(1, %d)", len2); + free(*ppsz_full_filename); + *ppsz_full_filename = NULL; + return NULL; + } + memcpy(ret_stat, statbuf, len2); + iso9660_filelist_free (entlist); + iso9660_dirlist_free(dirlist); + return ret_stat; } } @@ -1766,6 +1826,7 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, { unsigned offset = 0; uint8_t *_dirbuf = NULL; + uint32_t blocks; int ret; bool_3way_t have_rr = nope; @@ -1776,53 +1837,54 @@ iso_have_rr_traverse (iso9660_t *p_iso, const iso9660_stat_t *_root, 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) { - cdio_warn("Couldn't calloc(1, %d)", _root->secsize[0] * ISO_BLOCKSIZE); + cdio_warn("Couldn't calloc(1, %d)", blocks * ISO_BLOCKSIZE); return dunno; } - ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn[0], _root->secsize[0]); - if (ret!=ISO_BLOCKSIZE*_root->secsize[0]) { + ret = iso9660_iso_seek_read (p_iso, _dirbuf, _root->lsn, blocks); + if (ret != blocks * ISO_BLOCKSIZE) { free(_dirbuf); return false; } - while (offset < (_root->secsize[0] * ISO_BLOCKSIZE)) + while (offset < (blocks * ISO_BLOCKSIZE)) { iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset]; iso9660_stat_t *p_stat; unsigned int i_last_component = 1; if (iso9660_check_dir_block_end(p_iso9660_dir, &offset)) - continue; + continue; p_stat = _iso9660_dir_to_statbuf (p_iso9660_dir, NULL, p_iso->b_xa, p_iso->u_joliet_level); have_rr = p_stat->rr.b3_rock; if ( have_rr != yep) { - if (strlen(splitpath[0]) == 0) - have_rr = false; - else - have_rr = iso_have_rr_traverse (p_iso, p_stat, &splitpath[i_last_component], + if (strlen(splitpath[0]) == 0) + have_rr = false; + else + have_rr = iso_have_rr_traverse (p_iso, p_stat, &splitpath[i_last_component], pu_file_limit); } - free(p_stat); + iso9660_stat_free(p_stat); if (have_rr != nope) { - free (_dirbuf); - return have_rr; + free (_dirbuf); + return have_rr; } offset += iso9660_get_dir_len(p_iso9660_dir); *pu_file_limit = (*pu_file_limit)-1; if ((*pu_file_limit) == 0) { - free (_dirbuf); - return dunno; + free (_dirbuf); + return dunno; } } - cdio_assert (offset == (_root->secsize[0] * ISO_BLOCKSIZE)); + cdio_assert (offset == (blocks * ISO_BLOCKSIZE)); /* not found */ 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; 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[1]); diff --git a/src/libcdio/iso9660/rock.c b/src/libcdio/iso9660/rock.c index db15a2e0..b3a12d05 100644 --- a/src/libcdio/iso9660/rock.c +++ b/src/libcdio/iso9660/rock.c @@ -422,7 +422,7 @@ parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir, switch(p_sl->flags &~1){ case 0: 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]), p_sl->text, p_sl->len); p_stat->rr.i_symlink += p_sl->len; diff --git a/src/libcdio/udf/udf_time.c b/src/libcdio/udf/udf_time.c index 3da2d4a4..3d8a9f5f 100644 --- a/src/libcdio/udf/udf_time.c +++ b/src/libcdio/udf/udf_time.c @@ -133,12 +133,13 @@ udf_stamp_to_time(time_t *dest, long int *dest_usec, return NULL; } *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)] [src.month-1]) + (src.day-1)); - *dest += (time_t)src.second + ((time_t)SECS_PER_MINUTE * - ( ( ((time_t)yday* HOURS_PER_DAY) + src.hour ) * 60 + src.minute ) ); + *dest += src.second + + ( SECS_PER_MINUTE * + ( ( (yday* HOURS_PER_DAY) + src.hour ) * 60 + src.minute ) ); *dest_usec = src.microseconds + (src.centiseconds * 10000) diff --git a/src/rufus.rc b/src/rufus.rc index 47102957..359d8f4f 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.10.1656" +CAPTION "Rufus 3.10.1657" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -395,8 +395,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,10,1656,0 - PRODUCTVERSION 3,10,1656,0 + FILEVERSION 3,10,1657,0 + PRODUCTVERSION 3,10,1657,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -414,13 +414,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.10.1656" + VALUE "FileVersion", "3.10.1657" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2020 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.10.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.10.1656" + VALUE "ProductVersion", "3.10.1657" END END BLOCK "VarFileInfo"