2010-05-15 18:48:10 +00:00
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
2024-03-17 15:26:38 +00:00
Copyright 2007 - 2024 Thomas Schmitt , < scdbackup @ gmx . net >
2010-05-15 18:48:10 +00:00
Provided under GPL version 2 or later .
This file contains functions which operate on drives and media .
*/
2010-05-16 09:32:14 +00:00
# ifdef HAVE_CONFIG_H
# include "../config.h"
# endif
2010-05-15 18:48:10 +00:00
# include <ctype.h>
# include <sys/types.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <time.h>
# include <errno.h>
2012-05-01 07:49:46 +00:00
# include <pthread.h>
2010-05-15 18:48:10 +00:00
# include "xorriso.h"
# include "xorriso_private.h"
# include "lib_mgt.h"
# include "drive_mgt.h"
# include "iso_img.h"
# include "sort_cmp.h"
# include "write_run.h"
# include "read_run.h"
static const char * un0 ( const char * text )
{
if ( text = = NULL )
return ( " " ) ;
return ( text ) ;
}
int Xorriso_auto_driveadr ( struct XorrisO * xorriso , char * adr , char * result ,
int flag )
{
2011-09-23 13:18:11 +00:00
int ret , is_known_mmc = 0 , does_exist = 0 ;
2011-05-02 21:12:45 +00:00
char * path_pt , * libburn_adr = NULL ;
char * abs_pt , * abs_adr = NULL ;
2011-09-23 13:18:11 +00:00
struct stat stbuf ;
2010-05-15 18:48:10 +00:00
2011-05-02 21:12:45 +00:00
Xorriso_alloc_meM ( libburn_adr , char , BURN_DRIVE_ADR_LEN + SfileadrL ) ;
Xorriso_alloc_meM ( abs_adr , char , SfileadrL ) ;
2010-05-15 18:48:10 +00:00
path_pt = adr ;
if ( strncmp ( adr , " stdio: " , 6 ) = = 0 )
path_pt = adr + 6 ;
else if ( strncmp ( adr , " mmc: " , 4 ) = = 0 )
path_pt = adr + 4 ;
/* <<< replace by Xorriso_normalize_img_path() ? */ ;
if ( path_pt [ 0 ] ! = ' / ' ) {
abs_pt = getcwd ( abs_adr , SfileadrL - 1 ) ;
if ( abs_pt = = NULL ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" Relative drive path given. Cannot determine working directory. " ,
errno , " FAILURE " , 0 ) ;
2011-05-02 21:12:45 +00:00
{ ret = - 1 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
ret = Sfile_add_to_path ( abs_adr , path_pt , 0 ) ;
if ( ret < = 0 )
2011-05-02 21:12:45 +00:00
{ ret = - 1 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
is_known_mmc = burn_drive_convert_fs_adr ( path_pt , libburn_adr ) ;
2011-09-23 13:18:11 +00:00
does_exist = ( stat ( path_pt , & stbuf ) ! = - 1 ) ;
2010-05-15 18:48:10 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
ret = Xorriso_is_in_patternlist ( xorriso , xorriso - > drive_whitelist , path_pt , 0 ) ;
if ( ret > 0 )
goto ok ;
ret = Xorriso_is_in_patternlist ( xorriso , xorriso - > drive_blacklist , path_pt , 0 ) ;
if ( ret < 0 )
2011-05-02 21:12:45 +00:00
goto ex ;
2010-05-15 18:48:10 +00:00
if ( ret ) {
strcpy ( xorriso - > info_text , " Drive address " ) ;
Text_shellsafe ( adr , xorriso - > info_text , 1 ) ;
strcat ( xorriso - > info_text ,
" rejected because: -drive_class 'banned' " ) ;
Text_shellsafe ( Xorriso_get_pattern ( xorriso , xorriso - > drive_blacklist ,
ret - 1 , 0 ) ,
xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
2011-05-02 21:12:45 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
/* if in greylist and not MMC and not stdio prefix: reject */
if ( is_known_mmc < 0 )
2011-05-02 21:12:45 +00:00
goto ex ;
2010-05-15 18:48:10 +00:00
if ( adr = = path_pt & & ! is_known_mmc ) { /* no prefix, no MMC */
ret = Xorriso_is_in_patternlist ( xorriso , xorriso - > drive_greylist , path_pt , 0 ) ;
if ( ret < 0 )
2011-05-02 21:12:45 +00:00
goto ex ;
2010-05-15 18:48:10 +00:00
if ( ret ) {
strcpy ( xorriso - > info_text , " Drive address " ) ;
Text_shellsafe ( adr , xorriso - > info_text , 1 ) ;
2011-09-23 13:18:11 +00:00
strcat ( xorriso - > info_text , " rejected because: " ) ;
if ( does_exist )
strcat ( xorriso - > info_text , " not MMC " ) ;
else
strcat ( xorriso - > info_text , " not existing " ) ;
2015-03-03 20:20:14 +00:00
strcat ( xorriso - > info_text , " and -drive_class 'caution' " ) ;
2010-05-15 18:48:10 +00:00
Text_shellsafe ( Xorriso_get_pattern ( xorriso , xorriso - > drive_greylist ,
ret - 1 , 0 ) ,
xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
2011-09-23 13:18:11 +00:00
sprintf ( xorriso - > info_text ,
" If the address is a legitimate %s, prepend \" stdio: \" " ,
does_exist ? " target " : " address for a new regular file " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " HINT " , 0 ) ;
2011-05-02 21:12:45 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
}
ok : ;
if ( strncmp ( adr , " mmc: " , 4 ) = = 0 ) {
if ( Sfile_str ( result , path_pt , 0 ) < = 0 )
2011-05-02 21:12:45 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
} else if ( adr = = path_pt & & is_known_mmc < = 0 ) {
Sfile_str ( result , " stdio: " , 0 ) ;
if ( Sfile_str ( result , adr , 1 ) < = 0 )
2011-05-02 21:12:45 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
} else {
if ( Sfile_str ( result , adr , 0 ) < = 0 )
2011-05-02 21:12:45 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
if ( strncmp ( result , " stdio: " , 6 ) = = 0 ) {
if ( xorriso - > ban_stdio_write ) {
strcpy ( xorriso - > info_text , " Drive address banned by -ban_stdio_write : " ) ;
Text_shellsafe ( result , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
2011-05-02 21:12:45 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
}
2011-05-02 21:12:45 +00:00
ret = 1 ;
ex : ;
Xorriso_free_meM ( libburn_adr ) ;
Xorriso_free_meM ( abs_adr ) ;
return ( ret ) ;
2010-05-15 18:48:10 +00:00
}
2012-06-08 07:09:30 +00:00
static int Xorriso_grasp_loaded_aaip ( struct XorrisO * xorriso , IsoImage * volset ,
int flag )
{
2012-06-25 12:53:41 +00:00
int ret , change_pending_rec ;
2012-06-08 07:09:30 +00:00
IsoNode * root_node ;
size_t value_length ;
char * value = NULL ;
double num ;
struct FindjoB * job = NULL ;
struct stat dir_stbuf ;
2012-06-25 12:53:41 +00:00
/* To be re-instated at function end */
change_pending_rec = xorriso - > volset_change_pending ;
2012-06-08 07:09:30 +00:00
/* Look for isofs.st and put it into xorriso->isofs_st_in */
root_node = ( IsoNode * ) iso_image_get_root ( volset ) ;
ret = iso_node_lookup_attr ( root_node , " isofs.st " , & value_length , & value , 0 ) ;
if ( ret > 0 ) {
if ( value_length > 0 ) {
sscanf ( value , " %lf " , & num ) ;
if ( num > 0 )
xorriso - > isofs_st_in = num ;
}
free ( value ) ;
}
2024-07-22 12:42:22 +00:00
if ( ! ( xorriso - > do_aaip & ( 1 < < 11 ) ) ) {
/* lfa_flags not enabled for "read" */
ret = Xorriso_remove_all_lfa_flags ( xorriso , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
2012-06-08 07:09:30 +00:00
if ( xorriso - > do_hfsplus ) {
/* Bring isofs.hx to iso_hfsplus_xinfo_func,
isofs . hb to IsoImage blessings
*/
ret = Findjob_new ( & job , " / " , 0 ) ;
if ( ret < = 0 ) {
Xorriso_no_findjob ( xorriso , " xorriso " , 0 ) ;
{ ret = - 1 ; goto ex ; }
}
Findjob_set_action_target ( job , 49 , NULL , 0 ) ;
ret = Xorriso_findi ( xorriso , job , NULL , ( off_t ) 0 , NULL , " / " ,
& dir_stbuf , 0 , 0 ) ;
if ( ret < = 0 )
goto ex ;
2024-07-22 12:42:22 +00:00
Findjob_destroy ( & job , 0 ) ;
2012-06-08 07:09:30 +00:00
}
ret = 1 ;
ex : ;
2012-06-25 12:53:41 +00:00
xorriso - > volset_change_pending = change_pending_rec ;
2012-06-08 07:09:30 +00:00
Findjob_destroy ( & job , 0 ) ;
return ( ret ) ;
}
2020-08-26 14:29:40 +00:00
/* @param flag: bit0= set read speed
bit1 = set write speed
*/
int Xorriso_set_speed ( struct XorrisO * xorriso , struct burn_drive * drive ,
int read_speed , int write_speed , int flag )
{
int r_speed = 0 , w_speed = 0 , ret = 0 , profile_no = 0 ;
char profile_name [ 80 ] ;
if ( ( flag & 3 ) = = 0 )
return ( 0 ) ;
if ( xorriso - > read_speed = = - 2 ) {
if ( ! ( flag & 2 ) )
return ( 0 ) ;
}
if ( flag & 1 )
r_speed = read_speed ;
if ( flag & 2 )
w_speed = write_speed ;
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret < = 0 )
profile_no = 0 ;
if ( ( r_speed > 0 | | w_speed > 0 ) & & profile_no > = 0x10 ) {
ret = burn_drive_set_speed_exact ( drive , r_speed , w_speed ) ;
if ( ret > 0 )
goto ex ;
}
burn_drive_set_speed ( drive , r_speed , w_speed ) ;
ret = 2 ;
ex : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( ret ) ;
}
2022-10-07 09:55:10 +00:00
/* @param flag bit0= no info message "Loading ISO image tree"
*/
2022-09-20 08:28:25 +00:00
int Xorriso_make_read_options ( struct XorrisO * xorriso ,
struct burn_drive * drive ,
struct isoburn_read_opts * * ropts ,
int flag )
{
2024-03-18 21:43:29 +00:00
int ret , ext ;
off_t load_lba ;
2022-09-20 08:28:25 +00:00
enum burn_disc_status state ;
/* fill read opts */
ret = isoburn_ropt_new ( ropts , 0 ) ;
if ( ret < = 0 )
goto ex ;
ret = Xorriso_set_data_cache ( xorriso , * ropts , xorriso - > cache_num_tiles ,
xorriso - > cache_tile_blocks ,
xorriso - > cache_default ) ;
if ( ret < = 0 )
goto ex ;
ext = isoburn_ropt_noiso1999 ;
if ( xorriso - > read_fs & 1 )
ext | = isoburn_ropt_norock ;
if ( xorriso - > read_fs & 2 )
ext | = isoburn_ropt_nojoliet ;
2024-07-20 21:12:16 +00:00
if ( ( xorriso - > ino_behavior & ( 1 | 2 ) ) & &
! ( xorriso - > do_aaip & ( 1 | 4 | 32 | ( 1 < < 11 ) ) )
2022-09-20 08:28:25 +00:00
& & ! ( xorriso - > do_md5 & 1 ) & & ! ( xorriso - > do_hfsplus ) )
ext | = isoburn_ropt_noaaip ;
if ( ! ( xorriso - > do_aaip & 1 ) )
ext | = isoburn_ropt_noacl ;
if ( ! ( xorriso - > do_aaip & 4 ) )
ext | = isoburn_ropt_noea ;
2024-07-20 21:12:16 +00:00
if ( xorriso - > do_aaip & ( 1 < < 11 ) )
ext | = isoburn_ropt_lfa_flags ;
2024-08-27 09:01:37 +00:00
if ( xorriso - > do_aaip & ( 1 < < 15 ) )
ext | = isoburn_ropt_lfa_only_settable ;
2022-09-20 08:28:25 +00:00
if ( xorriso - > ino_behavior & 1 )
ext | = isoburn_ropt_noino ;
if ( ! ( xorriso - > do_md5 & 1 ) )
ext | = isoburn_ropt_nomd5 ;
if ( xorriso - > do_md5 & 32 )
ext | = isoburn_ropt_nomd5tag ;
if ( xorriso - > ecma119_map = = 0 )
ext | = isoburn_ropt_map_unmapped ;
else if ( xorriso - > ecma119_map = = 2 )
ext | = isoburn_ropt_map_uppercase ;
else if ( xorriso - > ecma119_map = = 3 )
ext | = isoburn_ropt_map_lowercase ;
else
ext | = isoburn_ropt_map_stripped ;
if ( xorriso - > joliet_map = = 0 )
ext | = isoburn_ropt_joliet_unmapped ;
else
ext | = isoburn_ropt_joliet_stripped ;
isoburn_ropt_set_extensions ( * ropts , ext ) ;
isoburn_ropt_set_default_perms ( * ropts , ( uid_t ) 0 , ( gid_t ) 0 , ( mode_t ) 0555 ) ;
isoburn_ropt_set_input_charset ( * ropts , xorriso - > in_charset ) ;
isoburn_ropt_set_auto_incharset ( * ropts , ! ! ( xorriso - > do_aaip & 512 ) ) ;
isoburn_ropt_set_displacement ( * ropts , xorriso - > displacement ,
xorriso - > displacement_sign ) ;
isoburn_ropt_set_truncate_mode ( * ropts , 1 , xorriso - > file_name_limit ) ;
Xorriso_set_image_severities ( xorriso , 1 ) ; /* No DEBUG messages */
/* <<< Trying to work around too much tolerance on bad image trees.
Better would be a chance to instruct libisofs what to do in
case of image read errors . There is a risk to mistake other SORRYs .
*/
if ( xorriso - > img_read_error_mode > 0 )
iso_set_abort_severity ( " SORRY " ) ;
state = isoburn_disc_get_status ( drive ) ;
if ( state ! = BURN_DISC_BLANK ) {
2024-03-18 21:43:29 +00:00
ret = isoburn_disc_get_msc1_v2 ( drive , & load_lba ) ;
2022-10-07 09:55:10 +00:00
if ( ret > 0 & & ! ( flag & 1 ) ) {
2022-09-20 08:28:25 +00:00
sprintf ( xorriso - > info_text ,
2024-03-18 21:43:29 +00:00
" Loading ISO image tree from LBA %.f " , ( double ) load_lba ) ;
2022-09-20 08:28:25 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
}
2024-03-20 21:38:23 +00:00
ret = Xorriso_assert_volid ( xorriso , load_lba , 0 ) ;
2022-09-20 08:28:25 +00:00
if ( ret < = 0 )
goto ex ;
}
Xorriso_set_speed ( xorriso , drive , xorriso - > read_speed , 0 , 1 ) ;
ret = 1 ;
ex :
return ( ret ) ;
}
2019-10-28 14:34:56 +00:00
/* @param flag bit0= acquire as isoburn input drive
bit1 = acquire as libburn output drive ( as isoburn drive if bit0 )
bit2 = regard overwritable media as blank
2010-05-15 18:48:10 +00:00
bit3 = if the drive is a regular disk file : truncate it to
the write start address
bit5 = do not print toc
2019-10-28 14:34:56 +00:00
bit6 = do not calm down drive after acquiring it
bit7 = re - assess rather than acquire :
2011-10-05 17:22:30 +00:00
Do not give up drives ,
use isoburn_drive_aquire ( ) with re - assessment bit
2010-05-15 18:48:10 +00:00
@ return < = 0 failure , 1 = ok
2 = success , but not writeable with bit1
3 = success , but not blank and not ISO with bit0
*/
2011-09-22 14:22:02 +00:00
int Xorriso_aquire_drive ( struct XorrisO * xorriso , char * adr , char * show_adr ,
int flag )
2010-05-15 18:48:10 +00:00
{
2022-09-20 08:28:25 +00:00
int ret , hret , not_writeable = 0 , has_what , aquire_flag ;
2024-03-19 11:24:00 +00:00
int track , session , params_flag , adr_mode , read_ret ;
off_t lba , start_lba ;
2015-09-25 17:15:41 +00:00
int truncate_mode ;
2010-09-10 17:13:00 +00:00
uint32_t size , offst ;
2011-10-05 17:22:30 +00:00
struct burn_drive_info * dinfo = NULL , * out_dinfo = NULL , * in_dinfo = NULL ;
struct burn_drive * drive = NULL , * out_drive = NULL , * in_drive = NULL ;
2010-05-15 18:48:10 +00:00
enum burn_disc_status state ;
IsoImage * volset = NULL ;
struct isoburn_read_opts * ropts = NULL ;
2011-09-22 14:22:02 +00:00
char * libburn_adr = NULL , * off_adr = NULL , * boot_fate , * sev ;
2011-05-04 15:24:09 +00:00
char volid [ 33 ] , * adr_data = NULL , * adr_pt ;
2011-05-02 21:12:45 +00:00
Xorriso_alloc_meM ( libburn_adr , char , SfileadrL ) ;
2011-09-22 14:22:02 +00:00
Xorriso_alloc_meM ( off_adr , char , SfileadrL ) ;
2011-05-02 21:12:45 +00:00
Xorriso_alloc_meM ( adr_data , char , 163 ) ;
2010-05-15 18:48:10 +00:00
2011-09-22 14:22:02 +00:00
if ( show_adr = = NULL ) {
show_adr = adr ;
ret = burn_drive_convert_fs_adr ( adr , off_adr ) ;
if ( ret > 0 )
adr = off_adr ;
}
2010-05-15 18:48:10 +00:00
if ( ( flag & 3 ) = = 0 ) {
sprintf ( xorriso - > info_text ,
" XORRISOBURN program error : Xorriso_aquire_drive bit0+bit1 not set " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FATAL " , 0 ) ;
2011-05-02 21:12:45 +00:00
{ ret = - 1 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
2011-10-05 17:22:30 +00:00
if ( ! ( flag & 128 ) ) {
ret = Xorriso_give_up_drive ( xorriso , ( flag & 3 ) | 8 ) ;
if ( ret < = 0 )
goto ex ;
}
2010-05-15 18:48:10 +00:00
if ( flag & 1 )
xorriso - > isofs_st_out = time ( 0 ) - 1 ;
ret = Xorriso_auto_driveadr ( xorriso , adr , libburn_adr , 0 ) ;
if ( ret < = 0 )
2011-05-02 21:12:45 +00:00
goto ex ;
2010-05-15 18:48:10 +00:00
if ( strcmp ( libburn_adr , " stdio:/dev/fd/1 " ) = = 0 ) {
if ( xorriso - > dev_fd_1 < 0 ) {
sprintf ( xorriso - > info_text ,
" -*dev \" stdio:/dev/fd/1 \" was not a start argument. Cannot use it now. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
} else {
sprintf ( libburn_adr , " stdio:/dev/fd/%d " , xorriso - > dev_fd_1 ) ;
}
}
2011-10-05 17:22:30 +00:00
if ( flag & 128 ) {
if ( flag & 1 )
Xorriso_get_drive_handles ( xorriso , & in_dinfo , & in_drive , " " , 16 ) ;
if ( flag & 2 )
Xorriso_get_drive_handles ( xorriso , & out_dinfo , & out_drive , " " , 2 | 16 ) ;
if ( in_dinfo ! = NULL & & ( out_dinfo = = NULL | | out_dinfo = = in_dinfo ) ) {
dinfo = in_dinfo ;
2019-09-08 10:30:52 +00:00
if ( flag & 2 ) {
2011-10-05 17:22:30 +00:00
xorriso - > outdev_is_exclusive = xorriso - > indev_is_exclusive ;
2019-09-08 10:30:52 +00:00
xorriso - > outdev_access = xorriso - > indev_access ;
}
2011-10-05 17:22:30 +00:00
} else if ( out_dinfo ! = NULL & & in_dinfo = = NULL ) {
dinfo = out_dinfo ;
2019-09-08 10:30:52 +00:00
if ( flag & 1 ) {
2011-10-05 17:22:30 +00:00
xorriso - > indev_is_exclusive = xorriso - > outdev_is_exclusive ;
2019-09-08 10:30:52 +00:00
xorriso - > indev_access = xorriso - > outdev_access ;
}
2011-10-05 17:22:30 +00:00
} else if ( out_dinfo ! = NULL | | in_dinfo ! = NULL ) {
sprintf ( xorriso - > info_text ,
" Two different drives shall be re-assed in one call " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FATAL " , 0 ) ;
{ ret = 0 ; goto ex ; }
} else {
2015-09-20 12:51:53 +00:00
sprintf ( xorriso - > info_text , " No drive acquired on re-assessment " ) ;
2011-10-05 17:22:30 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FATAL " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
} else if ( ( flag & 3 ) = = 1 & & xorriso - > out_drive_handle ! = NULL ) {
2010-05-15 18:48:10 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & out_dinfo , & out_drive ,
" on attempt to compare new indev with outdev " , 2 ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_drive_equals_adr ( out_drive , libburn_adr , 1 ) ;
if ( ret = = 1 ) {
dinfo = out_dinfo ;
xorriso - > indev_is_exclusive = xorriso - > outdev_is_exclusive ;
2019-09-08 10:30:52 +00:00
xorriso - > indev_access = xorriso - > outdev_access ;
2010-05-15 18:48:10 +00:00
}
} else if ( ( flag & 3 ) = = 2 & & xorriso - > in_drive_handle ! = NULL ) {
ret = Xorriso_get_drive_handles ( xorriso , & in_dinfo , & in_drive ,
" on attempt to compare new outdev with indev " , 0 ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_drive_equals_adr ( in_drive , libburn_adr , 1 ) ;
if ( ret = = 1 ) {
dinfo = in_dinfo ;
xorriso - > outdev_is_exclusive = xorriso - > indev_is_exclusive ;
2019-09-08 10:30:52 +00:00
xorriso - > outdev_access = xorriso - > indev_access ;
2010-05-15 18:48:10 +00:00
}
}
2011-10-05 17:22:30 +00:00
if ( dinfo = = NULL | | ( flag & 128 ) ) {
2010-05-15 18:48:10 +00:00
aquire_flag = 1 | ( ( flag & ( 8 | 4 ) ) > > 1 ) | ( ( xorriso - > toc_emulation_flag & 3 ) < < 3 ) ;
if ( xorriso - > toc_emulation_flag & 4 )
aquire_flag | = 128 ;
2012-08-14 10:32:35 +00:00
if ( xorriso - > toc_emulation_flag & 8 )
aquire_flag | = 512 ;
2010-05-15 18:48:10 +00:00
if ( ! ( xorriso - > do_aaip & 1 ) )
aquire_flag | = 32 ;
2017-10-23 10:08:16 +00:00
if ( ( xorriso - > ino_behavior & ( 1 | 2 ) ) & & ! ( xorriso - > do_aaip & ( 4 | 32 ) ) ) {
2010-05-15 18:48:10 +00:00
aquire_flag | = 64 ;
2017-10-23 10:08:16 +00:00
} else if ( xorriso - > do_aaip & 1024 ) {
aquire_flag | = 1024 ;
}
2024-07-20 21:12:16 +00:00
if ( xorriso - > do_aaip & ( 1 < < 11 ) )
aquire_flag | = 1 < < 11 ;
2024-08-27 09:01:37 +00:00
if ( xorriso - > do_aaip & ( 1 < < 15 ) )
aquire_flag | = 1 < < 15 ;
2011-10-05 17:22:30 +00:00
if ( flag & 128 )
aquire_flag | = 256 ;
2016-03-18 13:55:09 +00:00
burn_preset_device_open ( xorriso - > drives_exclusive |
( xorriso - > linux_scsi_dev_family < < 2 ) , 0 , 0 ) ;
2011-03-21 16:55:18 +00:00
burn_allow_drive_role_4 ( 1 | ( xorriso - > early_stdio_test & 14 ) ) ;
2010-05-15 18:48:10 +00:00
ret = isoburn_drive_aquire ( & dinfo , libburn_adr , aquire_flag ) ;
2016-03-18 13:55:09 +00:00
burn_preset_device_open ( 1 | ( xorriso - > linux_scsi_dev_family < < 2 ) , 0 , 0 ) ;
2010-05-15 18:48:10 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 ) {
2011-10-05 17:22:30 +00:00
if ( flag & 128 )
sprintf ( xorriso - > info_text , " Cannot re-assess drive '%s' " , adr ) ;
else
2016-02-05 14:57:52 +00:00
sprintf ( xorriso - > info_text , " Cannot acquire drive '%s' " , adr ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
ret = 0 ; goto ex ;
}
2016-07-31 07:38:41 +00:00
xorriso - > use_immed_bit_default = burn_drive_get_immed ( dinfo [ 0 ] . drive ) > 0 ?
1 : - 1 ;
if ( xorriso - > use_immed_bit ! = 0 )
burn_drive_set_immed ( dinfo [ 0 ] . drive , xorriso - > use_immed_bit > 0 ) ;
2010-09-10 17:13:00 +00:00
state = isoburn_disc_get_status ( dinfo [ 0 ] . drive ) ;
ret = isoburn_get_img_partition_offset ( dinfo [ 0 ] . drive , & offst ) ;
if ( ( state = = BURN_DISC_APPENDABLE | | state = = BURN_DISC_FULL ) & & ret = = 1 ) {
sprintf ( xorriso - > info_text ,
" ISO image bears MBR with -boot_image any partition_offset=%lu " ,
( unsigned long ) offst ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
}
2010-05-15 18:48:10 +00:00
if ( flag & 1 )
2019-08-12 19:08:41 +00:00
if ( xorriso - > image_start_mode & ( 1u < < 31 ) ) /* used up setting */
2010-05-15 18:48:10 +00:00
xorriso - > image_start_mode = 0 ; /* no need to perform auto setting */
2019-09-08 10:30:52 +00:00
if ( flag & 1 ) {
2010-05-15 18:48:10 +00:00
xorriso - > indev_is_exclusive = xorriso - > drives_exclusive ;
2019-09-08 10:30:52 +00:00
xorriso - > indev_access = xorriso - > drives_access ;
}
if ( flag & 2 ) {
2010-05-15 18:48:10 +00:00
xorriso - > outdev_is_exclusive = xorriso - > drives_exclusive ;
2019-09-08 10:30:52 +00:00
xorriso - > outdev_access = xorriso - > drives_access ;
}
2010-05-15 18:48:10 +00:00
}
drive = dinfo [ 0 ] . drive ;
2015-09-17 12:12:41 +00:00
volset = isoburn_get_attached_image ( drive ) ;
if ( volset ! = NULL ) {
ret = iso_image_set_truncate_mode ( volset , 1 , xorriso - > file_name_limit ) ;
2015-10-15 17:05:07 +00:00
iso_image_unref ( volset ) ;
volset = NULL ;
2015-09-17 12:12:41 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < 0 )
{ ret = 0 ; goto ex ; }
}
2010-09-10 17:13:00 +00:00
state = isoburn_disc_get_status ( drive ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2010-05-15 18:48:10 +00:00
if ( flag & 1 ) {
2019-08-12 19:08:41 +00:00
if ( xorriso - > image_start_mode & ( 1u < < 31 ) ) /* used up setting */
2010-05-15 18:48:10 +00:00
xorriso - > image_start_mode & = ~ 0xffff ; /* perform auto setting */
if ( ( xorriso - > image_start_mode & ( 1 < < 30 ) ) ) { /* if enabled at all */
adr_pt = xorriso - > image_start_value ;
adr_mode = xorriso - > image_start_mode & 0xffff ;
2024-06-29 21:31:15 +00:00
if ( adr_mode > = 4 & & adr_mode < = 9 & & strlen ( adr_pt ) < = 80 ) {
/* Convert volid search expression or time constraint to lba */
ret = Xorriso_prepare_load_search ( xorriso , " -indev " , adr_mode , adr_pt ,
adr_data , & params_flag , 0 ) ;
if ( ret < = 0 )
goto ex ;
ret = isoburn_get_mount_params_v2 ( drive , adr_mode , adr_data , & lba ,
& track , & session , volid , params_flag ) ;
2010-05-15 18:48:10 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 )
goto ex ;
if ( session < = 0 | | track < = 0 | | ret = = 2 ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" -load : Given address does not point to an ISO 9660 session " ,
0 , " FAILURE " , 0 ) ;
ret = 0 ; goto ex ;
}
2024-03-19 11:24:00 +00:00
sprintf ( volid , " %.f " , ( double ) lba ) ;
2010-05-15 18:48:10 +00:00
adr_pt = volid ;
adr_mode = 3 ;
}
ret = isoburn_set_msc1 ( drive , adr_mode , adr_pt ,
! ! ( xorriso - > image_start_mode & ( 1 < < 16 ) ) ) ;
if ( ret < = 0 )
goto ex ;
2019-08-12 19:08:41 +00:00
if ( xorriso - > image_start_mode & ( 1u < < 31 ) )
2010-05-15 18:48:10 +00:00
xorriso - > image_start_mode = 0 ; /* disable msc1 setting completely */
else
2019-08-12 19:08:41 +00:00
xorriso - > image_start_mode | = ( 1u < < 31 ) ; /* mark as used up */
2010-05-15 18:48:10 +00:00
}
}
if ( flag & 1 ) {
volset = isoburn_get_attached_image ( drive ) ;
if ( volset ! = NULL ) { /* The image object is already created */
iso_image_unref ( volset ) ;
2015-10-15 17:05:07 +00:00
volset = NULL ;
2010-05-15 18:48:10 +00:00
}
}
if ( flag & 2 ) {
xorriso - > out_drive_handle = dinfo ;
2011-09-22 14:22:02 +00:00
if ( Sfile_str ( xorriso - > outdev , show_adr , 0 ) < = 0 )
2010-05-15 18:48:10 +00:00
{ ret = - 1 ; goto ex ; }
2011-09-22 14:22:02 +00:00
ret = burn_drive_convert_fs_adr ( adr , xorriso - > outdev_off_adr ) ;
if ( ret < = 0 )
xorriso - > outdev_off_adr [ 0 ] = 0 ;
2010-05-15 18:48:10 +00:00
if ( state ! = BURN_DISC_BLANK & & state ! = BURN_DISC_APPENDABLE ) {
sprintf ( xorriso - > info_text , " Disc status unsuitable for writing " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
not_writeable = 1 ;
}
}
if ( flag & 1 ) {
xorriso - > in_drive_handle = dinfo ;
2011-09-22 14:22:02 +00:00
if ( Sfile_str ( xorriso - > indev , show_adr , 0 ) < = 0 )
2010-05-15 18:48:10 +00:00
{ ret = - 1 ; goto ex ; }
2011-09-22 14:22:02 +00:00
ret = burn_drive_convert_fs_adr ( adr , xorriso - > indev_off_adr ) ;
if ( ret < = 0 )
xorriso - > indev_off_adr [ 0 ] = 0 ;
2010-05-15 18:48:10 +00:00
} else if ( flag & 2 ) {
if ( xorriso - > in_volset_handle = = NULL ) {
/* No volume loaded: create empty one */
ret = Xorriso_create_empty_iso ( xorriso , 0 ) ;
if ( ret < = 0 )
goto ex ;
} else {
iso_image_ref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
2012-02-14 10:32:43 +00:00
start_lba = - 1 ;
ret = Xorriso_get_drive_handles ( xorriso , & in_dinfo , & in_drive ,
2012-02-29 13:54:38 +00:00
" on attempt to attach ISO image object to outdev " , 16 ) ;
2012-02-14 10:32:43 +00:00
if ( ret > 0 )
2024-03-19 11:24:00 +00:00
start_lba = isoburn_get_attached_start_lba_v2 ( in_drive ) ;
2010-05-15 18:48:10 +00:00
ret = isoburn_attach_image ( drive , ( IsoImage * ) xorriso - > in_volset_handle ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text ,
" Failed to attach ISO image object to outdev " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FATAL " , 0 ) ;
{ ret = - 1 ; goto ex ; }
}
2012-02-14 10:32:43 +00:00
if ( start_lba > = 0 )
2024-03-19 11:24:00 +00:00
isoburn_attach_start_lba_v2 ( drive , start_lba , 0 ) ;
2010-05-15 18:48:10 +00:00
}
if ( ! ( flag & 32 ) )
Xorriso_toc ( xorriso , 1 | 2 | 8 ) ;
{ ret = 1 + not_writeable ; goto ex ; }
}
if ( xorriso - > in_volset_handle ! = NULL )
iso_image_unref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
xorriso - > in_volset_handle = NULL ;
Sectorbitmap_destroy ( & ( xorriso - > in_sector_map ) , 0 ) ;
Xorriso_destroy_hln_array ( xorriso , 0 ) ;
Xorriso_destroy_di_array ( xorriso , 0 ) ;
2010-06-23 17:54:41 +00:00
xorriso - > boot_count = 0 ;
2015-12-23 11:18:38 +00:00
xorriso - > system_area_clear_loaded =
( strcmp ( xorriso - > system_area_disk_path , " /dev/zero " ) = = 0 ) ;
2010-05-15 18:48:10 +00:00
/* check for invalid state */
if ( state ! = BURN_DISC_BLANK & & state ! = BURN_DISC_APPENDABLE & &
state ! = BURN_DISC_FULL ) {
sprintf ( xorriso - > info_text ,
" Disc status not blank and unsuitable for reading " ) ;
sev = " FAILURE " ;
if ( xorriso - > img_read_error_mode = = 2 )
sev = " FATAL " ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , sev , 0 ) ;
Xorriso_give_up_drive ( xorriso , 1 | ( ( flag & 32 ) > > 2 ) ) ;
ret = 3 ; goto ex ;
}
2022-09-20 08:28:25 +00:00
ret = Xorriso_make_read_options ( xorriso , drive , & ropts , 0 ) ;
if ( ret < = 0 )
2012-03-11 16:41:10 +00:00
goto ex ;
2010-05-15 18:48:10 +00:00
Xorriso_pacifier_reset ( xorriso , 0 ) ;
isoburn_set_read_pacifier ( drive , Xorriso__read_pacifier , ( void * ) xorriso ) ;
read_ret = ret = isoburn_read_image ( drive , ropts , & volset ) ;
2022-09-20 08:28:25 +00:00
/* <<< Resetting to normal thresholds, after Xorriso_make_read_options */
2010-05-15 18:48:10 +00:00
if ( xorriso - > img_read_error_mode > 0 )
Xorriso_set_abort_severity ( xorriso , 0 ) ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
Xorriso_set_image_severities ( xorriso , 0 ) ;
Xorriso_give_up_drive ( xorriso , 1 | ( ( flag & 32 ) > > 2 ) ) ;
sprintf ( xorriso - > info_text , " Cannot read ISO image tree " ) ;
sev = " FAILURE " ;
if ( xorriso - > img_read_error_mode = = 2 )
sev = " FATAL " ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , sev , 0 ) ;
2011-05-09 18:12:16 +00:00
if ( read_ret = = ( int ) ISO_SB_TREE_CORRUPTED & & ( xorriso - > do_md5 & 1 ) ) {
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 ,
2011-03-09 07:14:49 +00:00
" This might be false MD5 alarm if an add-on session was written by growisofs. " ,
0 , " HINT " , 0 ) ;
Xorriso_msgs_submit ( xorriso , 0 ,
" In this case you get an ISO image tree by option -md5 'load_check_off' " ,
0 , " HINT " , 0 ) ;
2010-05-15 18:48:10 +00:00
} else if ( xorriso - > img_read_error_mode ! = 0 ) {
Xorriso_msgs_submit ( xorriso , 0 , " You might get a partial or altered ISO image tree by option -error_behavior 'image_loading' 'best_effort' if -abort_on is set to be tolerant enough. " ,
0 , " HINT " , 0 ) ;
}
ret = 3 ; goto ex ;
}
Xorriso_pacifier_callback ( xorriso , " nodes read " , xorriso - > pacifier_count , 0 ,
" " , 1 ) ; /* report end count */
xorriso - > in_volset_handle = ( void * ) volset ;
xorriso - > in_sector_map = NULL ;
Xorriso_set_image_severities ( xorriso , 0 ) ;
2015-09-25 17:15:41 +00:00
/* Might have changed due to isofs.nt */
iso_image_get_truncate_mode ( volset , & truncate_mode ,
& ( xorriso - > file_name_limit ) ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2010-05-15 18:48:10 +00:00
Xorriso_update_volid ( xorriso , 0 ) ;
strncpy ( xorriso - > application_id ,
un0 ( iso_image_get_application_id ( volset ) ) , 128 ) ;
xorriso - > application_id [ 128 ] = 0 ;
strncpy ( xorriso - > publisher , un0 ( iso_image_get_publisher_id ( volset ) ) , 128 ) ;
xorriso - > publisher [ 128 ] = 0 ;
strncpy ( xorriso - > system_id , un0 ( iso_image_get_system_id ( volset ) ) , 32 ) ;
xorriso - > system_id [ 32 ] = 0 ;
strncpy ( xorriso - > volset_id , un0 ( iso_image_get_volset_id ( volset ) ) , 128 ) ;
xorriso - > volset_id [ 128 ] = 0 ;
2010-06-26 11:40:36 +00:00
strncpy ( xorriso - > copyright_file ,
un0 ( iso_image_get_copyright_file_id ( volset ) ) , 37 ) ;
xorriso - > copyright_file [ 37 ] = 0 ;
strncpy ( xorriso - > biblio_file , un0 ( iso_image_get_biblio_file_id ( volset ) ) , 37 ) ;
xorriso - > biblio_file [ 37 ] = 0 ;
strncpy ( xorriso - > abstract_file ,
un0 ( iso_image_get_abstract_file_id ( volset ) ) , 37 ) ;
xorriso - > abstract_file [ 37 ] = 0 ;
2010-05-15 18:48:10 +00:00
if ( xorriso - > out_drive_handle ! = NULL & &
xorriso - > out_drive_handle ! = xorriso - > in_drive_handle ) {
2012-02-14 10:32:43 +00:00
start_lba = - 1 ;
ret = Xorriso_get_drive_handles ( xorriso , & in_dinfo , & in_drive ,
2012-02-29 13:54:38 +00:00
" on attempt to attach ISO image volset to outdev " , 16 ) ;
2012-02-14 10:32:43 +00:00
if ( ret > 0 )
2024-03-19 11:24:00 +00:00
start_lba = isoburn_get_attached_start_lba_v2 ( in_drive ) ;
2010-05-15 18:48:10 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & out_dinfo , & out_drive ,
" on attempt to attach ISO image volset to outdev " , 2 ) ;
if ( ret < = 0 )
goto ex ;
iso_image_ref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
isoburn_attach_image ( out_drive , xorriso - > in_volset_handle ) ;
2012-02-14 10:32:43 +00:00
if ( start_lba > = 0 )
2024-03-19 11:24:00 +00:00
isoburn_attach_start_lba_v2 ( out_drive , start_lba , 0 ) ;
2010-05-15 18:48:10 +00:00
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
isoburn_ropt_get_size_what ( ropts , & size , & has_what ) ;
2020-12-08 12:33:09 +00:00
xorriso - > isofs_size = size ;
2020-12-07 18:42:46 +00:00
xorriso - > isofs_has_what = has_what ;
isoburn_ropt_get_tree_loaded ( ropts , & ( xorriso - > tree_loaded ) ,
& ( xorriso - > rr_loaded ) ) ;
2010-05-15 18:48:10 +00:00
if ( has_what & isoburn_ropt_has_el_torito ) {
if ( xorriso - > boot_image_bin_path [ 0 ] )
boot_fate = " replaced by new boot image " ;
else if ( xorriso - > patch_isolinux_image & 1 )
boot_fate = " patched at boot info table " ;
else if ( xorriso - > keep_boot_image )
boot_fate = " kept unchanged " ;
else
boot_fate = " discarded " ;
sprintf ( xorriso - > info_text ,
" Detected El-Torito boot information which currently is set to be %s " ,
boot_fate ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
Xorriso_record_boot_info ( xorriso , 0 ) ;
}
if ( flag & 1 ) {
2012-06-08 07:09:30 +00:00
ret = Xorriso_grasp_loaded_aaip ( xorriso , volset , 0 ) ;
if ( ret < = 0 )
goto ex ;
2010-05-15 18:48:10 +00:00
}
if ( ! ( flag & 32 ) ) {
Xorriso_toc ( xorriso , 1 | 8 ) ;
2011-04-04 07:14:38 +00:00
if ( xorriso - > loaded_volid [ 0 ] ! = 0 & &
( state = = BURN_DISC_APPENDABLE | | state = = BURN_DISC_FULL ) ) {
sprintf ( xorriso - > info_text , " Volume id : '%s' \n " ,
xorriso - > loaded_volid ) ;
2010-05-15 18:48:10 +00:00
Xorriso_info ( xorriso , 0 ) ;
2011-04-04 07:14:38 +00:00
}
if ( strcmp ( xorriso - > loaded_volid , xorriso - > volid ) ! = 0 & &
! xorriso - > volid_default ) {
sprintf ( xorriso - > info_text , " New volume id: '%s' \n " , xorriso - > volid ) ;
Xorriso_info ( xorriso , 0 ) ;
2010-05-15 18:48:10 +00:00
}
}
ret = 1 + not_writeable ;
ex :
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 ) {
hret = Xorriso_give_up_drive ( xorriso , ( flag & 3 ) | ( ( flag & 32 ) > > 2 ) ) ;
if ( hret < ret )
ret = hret ;
} else {
if ( drive ! = NULL & & ( xorriso - > do_calm_drive & 1 ) & & ! ( flag & 64 ) )
burn_drive_snooze ( drive , 0 ) ; /* No need to make noise from start */
}
if ( ropts ! = NULL )
isoburn_ropt_destroy ( & ropts , 0 ) ;
2011-09-22 14:22:02 +00:00
Xorriso_free_meM ( off_adr ) ;
2011-05-02 21:12:45 +00:00
Xorriso_free_meM ( libburn_adr ) ;
Xorriso_free_meM ( adr_data ) ;
2010-05-15 18:48:10 +00:00
return ( ret ) ;
}
/* @param flag bit0=input drive
bit1 = output drive
bit2 = eject
bit3 = no info message or toc
*/
int Xorriso_give_up_drive ( struct XorrisO * xorriso , int flag )
{
2024-09-20 16:36:45 +00:00
int in_is_out_too , ret , do_eject , no_calm = 0 ;
2010-05-15 18:48:10 +00:00
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
in_is_out_too = ( xorriso - > in_drive_handle = = xorriso - > out_drive_handle ) ;
if ( ( flag & 4 ) & & in_is_out_too & & ( flag & ( 1 | 2 ) ) ) {
if ( ( flag & 3 ) ! = 3 ) {
2011-05-02 21:12:45 +00:00
sprintf ( xorriso - > info_text , " Giving up for -eject whole -dev " ) ;
Text_shellsafe ( xorriso - > indev , xorriso - > info_text , 1 ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
}
flag | = 3 ; /* give up in/out drive to eject it */
}
2024-09-20 16:36:45 +00:00
if ( xorriso - > do_calm_drive & 2 )
no_calm = 16 ;
2010-05-15 18:48:10 +00:00
if ( ( flag & 1 ) & & xorriso - > in_drive_handle ! = NULL ) {
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to give up drive " , 0 ) ;
if ( ! in_is_out_too ) {
do_eject = ! ! ( flag & 4 ) ;
2019-09-08 10:30:52 +00:00
if ( ( flag & 4 ) & & xorriso - > indev_access = = 0 ) {
2010-05-15 18:48:10 +00:00
sprintf ( xorriso - > info_text ,
2019-09-08 10:30:52 +00:00
" Will not eject medium in readonly acquired input drive. " ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
do_eject = 0 ;
}
if ( drive ! = NULL )
2024-09-20 16:36:45 +00:00
isoburn_drive_release_v2 ( drive , ( do_eject < < 1 ) | no_calm ) ;
2010-05-15 18:48:10 +00:00
if ( dinfo ! = NULL )
burn_drive_info_free ( dinfo ) ;
}
xorriso - > in_drive_handle = NULL ;
xorriso - > indev [ 0 ] = 0 ;
if ( xorriso - > in_volset_handle ! = NULL )
iso_image_unref ( ( IsoImage * ) xorriso - > in_volset_handle ) ;
xorriso - > in_volset_handle = NULL ;
Sectorbitmap_destroy ( & ( xorriso - > in_sector_map ) , 0 ) ;
Xorriso_destroy_di_array ( xorriso , 0 ) ;
Xorriso_destroy_hln_array ( xorriso , 0 ) ;
xorriso - > loaded_volid [ 0 ] = 0 ;
xorriso - > isofs_st_out = time ( 0 ) - 1 ;
xorriso - > isofs_st_in = 0 ;
xorriso - > volset_change_pending = 0 ;
xorriso - > no_volset_present = 0 ;
xorriso - > loaded_boot_bin_lba = 0 ;
xorriso - > loaded_boot_cat_path [ 0 ] = 0 ;
xorriso - > boot_count = 0 ;
in_is_out_too = 0 ;
}
if ( ( flag & 2 ) & & xorriso - > out_drive_handle ! = NULL ) {
do_eject = ! ! ( flag & 4 ) ;
2019-09-08 10:30:52 +00:00
if ( ( flag & 4 ) & & xorriso - > outdev_access = = 0 ) {
2010-05-15 18:48:10 +00:00
sprintf ( xorriso - > info_text ,
2019-09-08 10:30:52 +00:00
" Will not eject medium in readonly acquired drive. " ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
do_eject = 0 ;
}
2015-11-08 11:03:41 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to give up drive " , 2 ) ;
if ( ret > = 0 & & ! in_is_out_too ) {
2010-05-15 18:48:10 +00:00
if ( drive ! = NULL )
isoburn_drive_release ( drive , do_eject ) ;
if ( dinfo ! = NULL )
burn_drive_info_free ( dinfo ) ;
}
xorriso - > out_drive_handle = NULL ;
xorriso - > outdev [ 0 ] = 0 ;
2011-09-22 14:22:02 +00:00
xorriso - > outdev_off_adr [ 0 ] = 0 ;
2010-05-15 18:48:10 +00:00
} else if ( ( flag & 1 ) & & xorriso - > out_drive_handle ! = NULL ) {
ret = Xorriso_create_empty_iso ( xorriso , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
if ( ! ( flag & 8 ) ) {
sprintf ( xorriso - > info_text ,
" Only the output drive remains. Created empty ISO image. \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
Xorriso_toc ( xorriso , 1 | 2 | 8 ) ;
}
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
int Xorriso_may_burn ( struct XorrisO * xorriso , int flag )
{
2019-09-08 10:30:52 +00:00
if ( xorriso - > outdev_access = = 1 )
2010-05-15 18:48:10 +00:00
return ( 1 ) ;
2019-09-08 10:30:52 +00:00
sprintf ( xorriso - > info_text , " The output drive was acquired readonly. " ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
2019-09-08 10:30:52 +00:00
sprintf ( xorriso - > info_text , " Possible remedy: -drive_access \" exclusive:unrestricted \" . " ) ;
strcat ( xorriso - > info_text , " Then give up and re-acquire the drive. " ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " HINT " , 0 ) ;
2019-09-08 10:30:52 +00:00
if ( ! xorriso - > outdev_is_exclusive ) {
sprintf ( xorriso - > info_text , " If you insist in -drive_access \" shared:unrestricted \" , first read man xorriso about the risks. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " HINT " , 0 ) ;
}
2010-05-15 18:48:10 +00:00
return ( 0 ) ;
}
2013-02-26 10:33:01 +00:00
/* @param flag bit1=report about output drive rather than input drive
bit2 = do not try to read ISO heads
2010-05-15 18:48:10 +00:00
*/
int Xorriso_toc_to_string ( struct XorrisO * xorriso , char * * toc_text , int flag )
{
int ret , stack_handle , toc_ret , l ;
struct Xorriso_lsT * results = NULL , * infos = NULL , * lpt ;
* toc_text = NULL ;
ret = Xorriso_push_outlists ( xorriso , & stack_handle , 1 ) ;
if ( ret < = 0 )
goto ex ;
2013-02-26 10:33:01 +00:00
toc_ret = Xorriso_toc ( xorriso , flag & ( 2 | 4 ) ) ;
2010-05-15 18:48:10 +00:00
ret = Xorriso_pull_outlists ( xorriso , stack_handle , & results , & infos , 0 ) ;
if ( ret < = 0 )
goto ex ;
if ( toc_ret < = 0 )
{ ret = toc_ret ; goto ex ; }
l = 0 ;
for ( lpt = results ; lpt ! = NULL ; lpt = Xorriso_lst_get_next ( lpt , 0 ) )
l + = strlen ( Xorriso_lst_get_text ( lpt , 0 ) ) ;
* toc_text = calloc ( l + 1 , 1 ) ;
l = 0 ;
for ( lpt = results ; lpt ! = NULL ; lpt = Xorriso_lst_get_next ( lpt , 0 ) ) {
strcpy ( ( * toc_text ) + l , Xorriso_lst_get_text ( lpt , 0 ) ) ;
l + = strlen ( Xorriso_lst_get_text ( lpt , 0 ) ) ;
}
ex : ;
Xorriso_lst_destroy_all ( & results , 0 ) ;
Xorriso_lst_destroy_all ( & infos , 0 ) ;
return ( ret ) ;
}
2011-10-05 17:22:30 +00:00
/* @param flag bit0+1= what to give up and/or re-assess in what role
0 = give up outdev
1 = give up indev if not outdev , re - assess outdev as indev
2 = re - assess outdev as outdev
3 = give up indev if not outdev , re - assess outdev as dev
2010-05-15 18:48:10 +00:00
*/
int Xorriso_reaquire_outdev ( struct XorrisO * xorriso , int flag )
{
int ret , aq_flag ;
2011-09-22 14:22:02 +00:00
char * drive_name = NULL , * off_name = NULL ;
2010-05-15 18:48:10 +00:00
2011-05-02 21:12:45 +00:00
Xorriso_alloc_meM ( drive_name , char , SfileadrL ) ;
2011-09-22 14:22:02 +00:00
Xorriso_alloc_meM ( off_name , char , SfileadrL ) ;
2010-05-15 18:48:10 +00:00
aq_flag = flag & 3 ;
strcpy ( drive_name , xorriso - > outdev ) ;
2011-09-22 14:22:02 +00:00
if ( xorriso - > outdev_off_adr [ 0 ] )
strcpy ( off_name , xorriso - > outdev_off_adr ) ;
else
strcpy ( off_name , drive_name ) ;
2011-10-05 17:22:30 +00:00
if ( aq_flag = = 0 ) {
Xorriso_give_up_drive ( xorriso , 2 ) ;
2011-05-02 21:12:45 +00:00
sprintf ( xorriso - > info_text , " Gave up -outdev " ) ;
2011-10-05 17:22:30 +00:00
Text_shellsafe ( xorriso - > indev , xorriso - > info_text , 1 ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
2011-05-02 21:12:45 +00:00
{ ret = 1 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
2011-10-05 17:22:30 +00:00
/* Only give up indev, and only if it is not outdev */ ;
if ( xorriso - > in_drive_handle ! = xorriso - > out_drive_handle & &
xorriso - > in_drive_handle ! = NULL & & ( aq_flag & 1 ) )
Xorriso_give_up_drive ( xorriso , 1 | 8 ) ;
sprintf ( xorriso - > info_text , " Re-assessing -outdev " ) ;
2011-05-02 21:12:45 +00:00
Text_shellsafe ( drive_name , xorriso - > info_text , 1 ) ;
2011-09-22 14:22:02 +00:00
if ( strcmp ( drive_name , off_name ) ! = 0 ) {
strcat ( xorriso - > info_text , " ( " ) ;
Text_shellsafe ( off_name , xorriso - > info_text , 1 ) ;
strcat ( xorriso - > info_text , " ) " ) ;
}
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
2011-10-05 17:22:30 +00:00
/* Re-assess outdev */
ret = Xorriso_aquire_drive ( xorriso , off_name , drive_name , aq_flag | 128 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 ) {
2011-10-05 17:22:30 +00:00
sprintf ( xorriso - > info_text , " Could not re-assess -outdev " ) ;
2011-09-22 14:22:02 +00:00
Text_shellsafe ( drive_name , xorriso - > info_text , 1 ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
2011-05-02 21:12:45 +00:00
goto ex ;
2010-05-15 18:48:10 +00:00
}
2011-10-05 17:22:30 +00:00
2011-05-02 21:12:45 +00:00
ret = 1 ;
ex : ;
Xorriso_free_meM ( drive_name ) ;
2011-09-22 14:22:02 +00:00
Xorriso_free_meM ( off_name ) ;
2011-05-02 21:12:45 +00:00
return ( ret ) ;
2010-05-15 18:48:10 +00:00
}
/* @param flag
bit3 = report to info channel ( else to result channel )
*/
int Xorriso_toc_line ( struct XorrisO * xorriso , int flag )
{
if ( ! ( flag & 8 ) ) {
Xorriso_result ( xorriso , 0 ) ;
return ( 1 ) ;
}
strcpy ( xorriso - > info_text , xorriso - > result_line ) ;
Xorriso_info ( xorriso , 0 ) ;
return ( 1 ) ;
}
/* @param flag
bit1 = report about output drive
bit3 = report to info channel ( else to result channel )
2015-09-20 12:51:53 +00:00
bit4 = do no report failure if no drive acquired
2010-05-15 18:48:10 +00:00
*/
int Xorriso_media_product ( struct XorrisO * xorriso , int flag )
{
int ret , profile_no ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
char * product_id = NULL , * media_code1 = NULL , * media_code2 = NULL ;
char * book_type = NULL , * manuf = NULL , profile_name [ 80 ] , * respt ;
respt = xorriso - > result_line ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to print media product info " ,
flag & ( 2 | 16 ) ) ;
if ( ret < = 0 )
return ( ret ) ;
ret = burn_disc_get_media_id ( drive , & product_id , & media_code1 , & media_code2 ,
& book_type , 0 ) ;
if ( ret > 0 ) {
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret < = 0 )
return ( ret ) ;
sprintf ( respt , " Media product: %s , " , product_id ) ;
manuf = burn_guess_manufacturer ( profile_no , media_code1 , media_code2 , 0 ) ;
if ( manuf ! = NULL ) {
if ( strncmp ( manuf , " Unknown " , 8 ) = = 0 )
sprintf ( respt + strlen ( respt ) , " (not found in manufacturer list) \n " ) ;
else
sprintf ( respt + strlen ( respt ) , " %s \n " , manuf ) ;
} else
sprintf ( respt + strlen ( respt ) , " (error during manufacturer lookup) \n " ) ;
free ( product_id ) ;
free ( media_code1 ) ;
free ( media_code2 ) ;
if ( book_type ! = NULL )
free ( book_type ) ;
if ( manuf ! = NULL )
free ( manuf ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
/* @param flag bit0=short report form
bit1 = report about output drive
bit2 = do not try to read ISO heads
bit3 = report to info channel ( else to result channel )
2015-09-20 12:51:53 +00:00
bit4 = do no report failure if no drive acquired
2010-05-15 18:48:10 +00:00
bit5 = only report " Drive current " and " Drive type "
bit6 = report " Media product " with bit0
bit7 = only report " Drive current "
*/
int Xorriso_toc ( struct XorrisO * xorriso , int flag )
{
2024-03-19 18:59:06 +00:00
int num_sessions = 0 , num_tracks = 0 , ret ;
int track_count = 0 , session_no , track_no , profile_no = - 1 ;
int is_data = 0 ;
int is_inout_drive = 0 , drive_role , status , num_formats ;
int not_recognizable = 0 ;
2013-01-14 09:45:20 +00:00
int sessions_seen , open_sessions = 0 , have_real_open_session = 0 ;
2010-05-15 18:48:10 +00:00
char profile_name [ 80 ] , * respt , * devadr , * typetext = " " ;
struct burn_toc_entry toc_entry ;
struct burn_drive_info * dinfo ;
2011-05-26 15:18:41 +00:00
struct burn_multi_caps * caps = NULL ;
2010-05-15 18:48:10 +00:00
struct burn_drive * drive ;
enum burn_disc_status s ;
2023-01-09 14:45:00 +00:00
char mem_text [ 80 ] , * num_free_text , * num_data_text ;
2010-05-15 18:48:10 +00:00
off_t start_byte = 0 , num_free = 0 , size ;
unsigned dummy ;
struct isoburn_toc_disc * disc = NULL ;
struct isoburn_toc_session * * sessions ;
struct isoburn_toc_track * * tracks ;
char volume_id [ 33 ] ;
struct burn_toc_entry next_toc_entry ;
2011-08-01 13:04:14 +00:00
int disk_category , part_version , num_layers , num_blocks ;
char * book_name ;
2011-10-13 10:59:48 +00:00
int num_data_from_format = 0 ;
2015-10-18 13:00:02 +00:00
char * sno = NULL ;
2024-03-19 18:59:06 +00:00
int sno_len , i , is_bdr_pow = 0 , int_start_lba = - 1 , int_end_lba = - 1 ;
off_t lba = 0 , nwa = - 1 , track_size , session_size , first_track_start = 0 ;
2024-05-19 07:42:12 +00:00
off_t num_session_data , num_session_other , num_data = 0 , other_data = 0 ;
2024-03-19 18:59:06 +00:00
off_t emul_lba , end_lba , image_blocks , overburn_blocks = 0 ;
2024-06-28 14:42:28 +00:00
int info_type ;
static char * info_type_name [ ] = { " " , " Volume Id " , " " , " Creation Time " ,
" Modification Time " } ;
static int max_info_type = 4 ;
info_type = xorriso - > toc_info_type ;
if ( info_type < 1 | | info_type > max_info_type )
info_type = 1 ;
2010-05-15 18:48:10 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to print Table Of Content " ,
flag & ( 2 | 16 ) ) ;
if ( ret < = 0 )
{ ret = 0 ; goto ex ; }
respt = xorriso - > result_line ;
if ( strcmp ( xorriso - > indev , xorriso - > outdev ) = = 0 )
is_inout_drive = 1 ;
if ( flag & 2 )
devadr = xorriso - > outdev ;
else
devadr = xorriso - > indev ;
sprintf ( respt , " Drive current: %s '%s' \n " ,
( is_inout_drive ? " -dev " : ( flag & 2 ? " -outdev " : " -indev " ) ) ,
devadr ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( flag & 128 )
{ ret = 1 ; goto ex ; }
2019-09-08 10:30:52 +00:00
/* Report -drive_access if non-default or if long form */
respt [ 0 ] = 0 ;
if ( flag & 2 ) {
if ( xorriso - > outdev_is_exclusive = = 0 | | xorriso - > outdev_access = = 0 | |
! ( flag & 33 ) ) {
sprintf ( respt , " Drive access : %s:%s \n " ,
xorriso - > outdev_is_exclusive ? " exclusive " : " shared " ,
xorriso - > outdev_access = = 0 ? " readonly " : " unrestricted " ) ;
}
} else {
if ( xorriso - > indev_is_exclusive = = 0 | | xorriso - > indev_access = = 0 | |
! ( flag & 33 ) ) {
sprintf ( respt , " Drive access : %s:%s \n " ,
xorriso - > indev_is_exclusive ? " exclusive " : " shared " ,
xorriso - > indev_access = = 0 ? " readonly " : " unrestricted " ) ;
}
}
if ( respt [ 0 ] )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
2010-05-15 18:48:10 +00:00
sprintf ( respt , " Drive type : vendor '%s' product '%s' revision '%s' \n " ,
dinfo [ 0 ] . vendor , dinfo [ 0 ] . product , dinfo [ 0 ] . revision ) ;
2011-08-01 13:04:14 +00:00
if ( ( flag & 32 ) | | ! ( flag & 1 ) )
2010-05-15 18:48:10 +00:00
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( flag & 32 )
{ ret = 1 ; goto ex ; }
2015-10-18 13:00:02 +00:00
if ( ! ( flag & 1 ) ) {
burn_drive_get_serial_no ( drive , & sno , & sno_len ) ;
if ( sno_len > 0 ) {
sprintf ( respt , " Drive id : '%s' \n " , sno ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
if ( sno ! = NULL )
free ( sno ) ;
sno = NULL ;
}
2010-05-15 18:48:10 +00:00
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
s = isoburn_disc_get_status ( drive ) ;
if ( profile_no = = 0x0002 & & s = = BURN_DISC_EMPTY )
profile_no = 0 ;
2017-02-13 14:52:36 +00:00
is_bdr_pow = burn_drive_get_bd_r_pow ( drive ) ;
2010-05-15 18:48:10 +00:00
sprintf ( respt , " Media current: " ) ;
2011-03-21 09:37:02 +00:00
drive_role = burn_drive_get_drive_role ( drive ) ;
2010-05-15 18:48:10 +00:00
if ( profile_no > 0 & & ret > 0 ) {
if ( profile_name [ 0 ] )
sprintf ( respt + strlen ( respt ) , " %s " , profile_name ) ;
else
sprintf ( respt + strlen ( respt ) , " %4.4Xh " , profile_no ) ;
2017-02-13 14:52:36 +00:00
if ( is_bdr_pow )
sprintf ( respt + strlen ( respt ) , " , Pseudo Overwrite formatted " ) ;
else if ( drive_role = = 2 )
2010-05-15 18:48:10 +00:00
sprintf ( respt + strlen ( respt ) , " , overwriteable " ) ;
2011-03-21 09:37:02 +00:00
else if ( drive_role = = 4 )
sprintf ( respt + strlen ( respt ) , " , random read-only " ) ;
else if ( drive_role = = 5 )
sprintf ( respt + strlen ( respt ) , " , random write-only " ) ;
2010-05-15 18:48:10 +00:00
else if ( drive_role = = 0 | | drive_role = = 3 )
sprintf ( respt + strlen ( respt ) , " , sequential " ) ;
strcat ( respt , " \n " ) ;
} else {
sprintf ( respt + strlen ( respt ) , " is not recognizable \n " ) ;
2011-07-12 13:56:36 +00:00
not_recognizable = 1 ;
2010-05-15 18:48:10 +00:00
}
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( ( flag & 64 ) | | ! ( flag & 1 ) ) {
Xorriso_media_product ( xorriso , flag & ( 2 | 8 | 16 ) ) ;
if ( xorriso - > request_to_abort )
{ ret = 1 ; goto ex ; }
}
sprintf ( respt , " Media status : " ) ;
2017-02-13 14:52:36 +00:00
if ( is_bdr_pow ) {
sprintf ( respt + strlen ( respt ) , " is unsuitable , is POW formatted " ) ;
} else if ( s = = BURN_DISC_FULL ) {
2011-07-12 13:56:36 +00:00
if ( not_recognizable )
2010-05-15 18:48:10 +00:00
sprintf ( respt + strlen ( respt ) , " is not recognizable \n " ) ;
else
2011-05-26 15:18:41 +00:00
sprintf ( respt + strlen ( respt ) , " is written , is closed " ) ;
2010-05-15 18:48:10 +00:00
} else if ( s = = BURN_DISC_APPENDABLE ) {
2011-05-26 15:18:41 +00:00
sprintf ( respt + strlen ( respt ) , " is written , is appendable " ) ;
2010-05-15 18:48:10 +00:00
} else if ( s = = BURN_DISC_BLANK ) {
2011-05-26 15:18:41 +00:00
sprintf ( respt + strlen ( respt ) , " is blank " ) ;
2010-05-15 18:48:10 +00:00
} else if ( s = = BURN_DISC_EMPTY )
2011-05-26 15:18:41 +00:00
sprintf ( respt + strlen ( respt ) , " is not present " ) ;
2010-05-15 18:48:10 +00:00
else
2011-05-26 15:18:41 +00:00
sprintf ( respt + strlen ( respt ) , " is not recognizable " ) ;
if ( s = = BURN_DISC_APPENDABLE | | s = = BURN_DISC_BLANK ) {
ret = burn_disc_next_track_is_damaged ( drive , 0 ) ;
if ( ret & 1 )
sprintf ( respt + strlen ( respt ) , " , but next track is damaged " ) ;
else if ( ret & 2 )
sprintf ( respt + strlen ( respt ) , " , but no writable address " ) ;
else if ( profile_no = = 0x14 ) { /* DVD-RW sequential */
ret = burn_disc_get_multi_caps ( drive , BURN_WRITE_TAO , & caps , 0 ) ;
if ( ret = = 0 )
2011-05-29 09:56:23 +00:00
sprintf ( respt + strlen ( respt ) , " , but will need -close on " ) ;
2011-05-26 15:18:41 +00:00
if ( caps ! = NULL )
burn_disc_free_multi_caps ( & caps ) ;
} else if ( profile_no = = 0x15 ) { /* DVD-RW DL */
sprintf ( respt + strlen ( respt ) , " , but will need -close \" on \" " ) ;
}
}
strcat ( respt , " \n " ) ;
2010-05-15 18:48:10 +00:00
Xorriso_toc_line ( xorriso , flag & 8 ) ;
2011-08-01 13:04:14 +00:00
if ( ( s = = BURN_DISC_FULL | | s = = BURN_DISC_APPENDABLE | |
s = = BURN_DISC_BLANK ) & & ! ( flag & 1 ) ) {
2015-10-18 13:00:02 +00:00
burn_drive_get_media_sno ( drive , & sno , & sno_len ) ;
if ( sno_len > 0 ) {
sprintf ( respt , " Media id : " ) ;
respt + = strlen ( respt ) ;
for ( i = 0 ; i < sno_len & & i < 1024 ; i + + ) {
sprintf ( respt , " %2.2X " , ( unsigned int ) ( ( unsigned char * ) sno ) [ i ] ) ;
respt + = 2 ;
}
if ( i < sno_len )
strcat ( respt , " ... " ) ;
strcat ( respt , " \n " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
if ( sno ! = NULL )
free ( sno ) ;
sno = NULL ;
respt = xorriso - > result_line ;
2024-03-19 18:59:06 +00:00
ret = burn_get_read_capacity_v2 ( drive , & num_data , 0 ) ;
2011-08-01 13:04:14 +00:00
if ( ret ! = 1 | | s = = BURN_DISC_BLANK )
num_data = 0 ;
num_free = isoburn_disc_available_space ( drive , NULL ) / 2048 ;
nwa = - 1 ;
if ( s = = BURN_DISC_APPENDABLE ) {
2024-03-19 18:59:06 +00:00
ret = isoburn_disc_track_lba_nwa_v2 ( drive , NULL , 0 , & lba , & nwa ) ;
2011-08-01 13:04:14 +00:00
if ( ret < = 0 )
nwa = - 1 ;
} else if ( s = = BURN_DISC_BLANK ) {
2024-03-19 18:59:06 +00:00
ret = isoburn_disc_track_lba_nwa_v2 ( drive , NULL , 0 , & lba , & nwa ) ;
2011-08-01 13:04:14 +00:00
if ( ret = = 1 ) {
num_free + = nwa ;
nwa = 0 ;
}
}
lba = num_data + num_free ;
if ( nwa > = 0 ) {
lba = nwa + num_free ;
if ( nwa < num_data )
num_data = nwa ;
}
/* If closed CD-RW : obtain ATIP lead out address */
if ( profile_no = = 0x0a ) {
ret = burn_disc_read_atip ( drive ) ;
if ( ret < 0 )
goto ex ;
2024-03-19 18:59:06 +00:00
ret = burn_drive_get_start_end_lba ( drive , & int_start_lba , & int_end_lba , 0 ) ;
end_lba = int_end_lba ;
2011-08-01 13:04:14 +00:00
if ( s = = BURN_DISC_FULL & & ret = = 1 ) {
2021-11-24 11:52:53 +00:00
if ( lba > end_lba - 2 ) {
overburn_blocks = lba - end_lba + 2 ;
} else {
lba = end_lba - 2 ;
}
2011-08-01 13:04:14 +00:00
} else {
if ( ret = = 1 & & end_lba - 2 > lba ) {
sprintf ( xorriso - > info_text ,
2024-03-19 18:59:06 +00:00
" ATIP end_lba %.f > overall %.f " , ( double ) end_lba , ( double ) lba ) ;
2011-08-01 13:04:14 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
}
}
} else if ( profile_no = = 0x14 ) {
ret = burn_disc_get_phys_format_info ( drive , & disk_category ,
& book_name , & part_version ,
& num_layers , & num_blocks , 0 ) ;
if ( ret = = 1 & & num_blocks > lba )
lba = num_blocks ;
}
2023-01-09 14:45:00 +00:00
if ( drive_role = = 5 )
num_data_text = " occupied " ;
else
num_data_text = " readable " ;
2017-02-13 14:52:36 +00:00
if ( drive_role = = 4 | | is_bdr_pow )
2012-01-18 09:35:43 +00:00
num_free_text = " unused " ;
else
num_free_text = " writable " ;
2024-03-19 18:59:06 +00:00
sprintf ( respt , " Media blocks : %.f %s , %.f %s , %.f overall \n " ,
( double ) num_data , num_data_text ,
( double ) num_free , num_free_text , ( double ) lba ) ;
2011-08-01 13:04:14 +00:00
Xorriso_toc_line ( xorriso , flag & 8 ) ;
2021-11-24 11:52:53 +00:00
if ( overburn_blocks > 0 ) {
2024-03-19 18:59:06 +00:00
sprintf ( respt , " Overburnt by : %.f blocks \n " , ( double ) overburn_blocks ) ;
2021-11-24 11:52:53 +00:00
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
2011-08-01 13:04:14 +00:00
}
2010-05-15 18:48:10 +00:00
if ( s = = BURN_DISC_BLANK ) {
sprintf ( respt , " Media summary: 0 sessions, 0 data blocks, 0 data " ) ;
num_free = isoburn_disc_available_space ( drive , NULL ) ;
Sfile_scale ( ( double ) num_free , mem_text , 5 , 1e4 , 1 ) ;
sprintf ( respt + strlen ( respt ) , " , %s free \n " , mem_text ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
if ( s ! = BURN_DISC_FULL & & s ! = BURN_DISC_APPENDABLE )
{ ret = 1 ; goto ex ; }
if ( xorriso - > request_to_abort )
{ ret = 1 ; goto ex ; }
2017-02-13 14:52:36 +00:00
if ( is_bdr_pow ) {
sprintf ( respt ,
" Media summary: unsuitable Pseudo Overwrite formatted BD-R \n " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
{ ret = 1 ; goto ex ; }
}
2010-05-15 18:48:10 +00:00
if ( ! ( flag & 2 ) )
Xorriso_show_boot_info ( xorriso , 1 | ( flag & 8 ) | ( ( flag & 1 ) < < 1 ) ) ;
2020-12-08 12:33:09 +00:00
if ( xorriso - > isofs_size > 0 & & ! ( flag & 3 ) ) {
2020-12-07 18:42:46 +00:00
sprintf ( respt , " ISO offers :%s%s%s%s \n " ,
xorriso - > isofs_has_what & 1 ? " Rock_Ridge " : " " ,
xorriso - > isofs_has_what & 2 ? " Joliet " : " " ,
xorriso - > isofs_has_what & 4 ? " ISO_9660_1999 " : " " ,
xorriso - > isofs_has_what & 7 ? " " : " Only_ECMA_119 " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
sprintf ( respt , " ISO loaded : %s \n " ,
xorriso - > tree_loaded = = 1 ? " Joliet " :
xorriso - > tree_loaded = = 2 ? " ISO_9660_1999 " :
xorriso - > rr_loaded > 0 ? " Rock_Ridge " : " Only_ECMA_119 " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
2010-05-15 18:48:10 +00:00
disc = isoburn_toc_drive_get_disc ( drive ) ;
if ( flag & 4 )
sprintf ( respt , " TOC layout : %3s , %9s , %10s \n " ,
" Idx " , " sbsector " , " Size " ) ;
else
sprintf ( respt , " TOC layout : %3s , %9s , %10s , %s \n " ,
2024-06-28 14:42:28 +00:00
" Idx " , " sbsector " , " Size " , info_type_name [ info_type ] ) ;
2010-05-15 18:48:10 +00:00
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
if ( disc = = NULL ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2023-01-09 14:45:00 +00:00
nwa = 0 ;
2011-03-21 09:37:02 +00:00
if ( drive_role = = 5 & & s = = BURN_DISC_APPENDABLE ) {
2024-03-19 18:59:06 +00:00
ret = burn_disc_track_lba_nwa_v2 ( drive , NULL , 0 , & lba , & nwa ) ;
2011-07-24 19:34:52 +00:00
if ( ret ! = 1 )
2023-01-09 14:45:00 +00:00
nwa = 0 ;
2011-03-21 09:37:02 +00:00
} else {
ret = isoburn_get_min_start_byte ( drive , & start_byte , 0 ) ;
nwa = start_byte / 2048 ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( flag & 1 )
2011-07-12 13:56:36 +00:00
{ ret = 1 ; goto ex ; }
2011-03-21 09:37:02 +00:00
sprintf ( xorriso - > info_text , " Cannot obtain Table Of Content " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
2010-05-15 18:48:10 +00:00
{ ret = 0 ; goto ex ; }
2011-03-21 09:37:02 +00:00
}
2010-05-15 18:48:10 +00:00
}
/* fabricate TOC */
typetext = " Other session " ;
if ( flag & 4 ) {
ret = 0 ;
typetext = " Session " ;
2024-06-28 14:42:28 +00:00
} else {
ret = isoburn_read_iso_head_v2 ( drive , 0 , & image_blocks , volume_id ,
info_type ) ;
if ( ret > 0 & & ( info_type = = 3 | | info_type = = 4 ) )
Untimezone_ecma119_17byte ( volume_id , ( xorriso - > toc_time_form & 1 ) | 2 ) ;
}
2010-05-15 18:48:10 +00:00
if ( ret > 0 ) {
2024-03-19 18:59:06 +00:00
sprintf ( respt , " ISO session : %3d , %9d , %9.fs , %s \n " ,
1 , 0 , ( double ) image_blocks , volume_id ) ;
2010-05-15 18:48:10 +00:00
nwa = image_blocks ;
} else {
ret = burn_disc_get_formats ( drive , & status , & size , & dummy ,
& num_formats ) ;
2011-07-24 19:34:52 +00:00
if ( ret < = 0 | | status ! = BURN_FORMAT_IS_FORMATTED )
size = 0 ;
if ( size < = 0 ) {
2024-03-19 18:59:06 +00:00
ret = burn_get_read_capacity_v2 ( drive , & num_data , 0 ) ;
2011-07-24 19:34:52 +00:00
if ( ret = = 1 )
2024-03-19 18:59:06 +00:00
size = num_data * ( off_t ) 2048 ;
2011-10-13 10:59:48 +00:00
} else {
num_data_from_format = 1 ;
2011-07-24 19:34:52 +00:00
}
2023-01-09 14:45:00 +00:00
num_data = size / 2048 ;
if ( num_data = = 0 & & drive_role = = 5 & & s = = BURN_DISC_APPENDABLE )
num_data = nwa ;
2024-03-19 18:59:06 +00:00
sprintf ( respt , " %13s: %3d , %9d , %9.fs , \n " ,
typetext , 1 , 0 , ( double ) num_data ) ;
2010-05-15 18:48:10 +00:00
}
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
num_sessions = 1 ;
} else {
2019-07-13 15:30:47 +00:00
num_data = other_data = 0 ;
2010-05-15 18:48:10 +00:00
sessions = isoburn_toc_disc_get_sessions ( disc , & num_sessions ) ;
2013-01-14 09:45:20 +00:00
open_sessions = isoburn_toc_disc_get_incmpl_sess ( disc ) ;
for ( session_no = 0 ;
session_no < num_sessions + open_sessions & &
! ( xorriso - > request_to_abort ) ;
2010-05-15 18:48:10 +00:00
session_no + + ) {
2019-07-13 15:30:47 +00:00
num_session_data = num_session_other = 0 ;
2010-05-15 18:48:10 +00:00
tracks = isoburn_toc_session_get_tracks ( sessions [ session_no ] , & num_tracks ) ;
2013-01-14 09:45:20 +00:00
if ( tracks = = NULL | | num_tracks < = 0 )
2010-05-15 18:48:10 +00:00
continue ;
2013-01-14 09:45:20 +00:00
if ( session_no = = num_sessions + open_sessions - 1 & & open_sessions > 0 )
have_real_open_session = 1 ;
2010-05-15 18:48:10 +00:00
for ( track_no = 0 ; track_no < num_tracks & & ! ( xorriso - > request_to_abort ) ;
track_no + + ) {
track_count + + ;
is_data = 0 ;
isoburn_toc_track_get_entry ( tracks [ track_no ] , & toc_entry ) ;
2019-07-13 15:30:47 +00:00
if ( ( toc_entry . control & 7 ) > = 4 ) /* data track */
is_data = 1 ;
2024-03-19 18:59:06 +00:00
if ( toc_entry . extensions_valid & 8 ) {
lba = toc_entry . long_start_lba ;
track_size = toc_entry . long_track_blocks ;
} else if ( toc_entry . extensions_valid & 1 ) {
2010-05-15 18:48:10 +00:00
/* DVD extension valid */
lba = toc_entry . start_lba ;
track_size = toc_entry . track_blocks ;
} else {
lba = burn_msf_to_lba ( toc_entry . pmin , toc_entry . psec ,
toc_entry . pframe ) ;
if ( track_no = = num_tracks - 1 ) {
isoburn_toc_session_get_leadout_entry ( sessions [ session_no ] ,
& next_toc_entry ) ;
} else {
isoburn_toc_track_get_entry ( tracks [ track_no + 1 ] , & next_toc_entry ) ;
}
track_size = burn_msf_to_lba ( next_toc_entry . pmin , next_toc_entry . psec ,
next_toc_entry . pframe ) - lba ;
}
2019-07-13 15:30:47 +00:00
if ( ( flag & ( 1 | 4 ) ) | | ! is_data ) {
2010-05-15 18:48:10 +00:00
ret = 0 ;
2019-07-13 15:30:47 +00:00
} else {
2024-03-19 18:59:06 +00:00
ret = isoburn_toc_track_get_emul_v2 ( tracks [ track_no ] , & emul_lba ,
& image_blocks , volume_id , 0 ) ;
2024-06-28 14:42:28 +00:00
if ( ret < = 0 | | info_type ! = 1 ) {
2024-03-19 18:59:06 +00:00
ret = isoburn_read_iso_head_v2 ( drive , lba , & image_blocks , volume_id ,
2024-06-28 14:42:28 +00:00
info_type ) ;
if ( ret > 0 & & ( info_type = = 3 | | info_type = = 4 ) )
Untimezone_ecma119_17byte ( volume_id ,
( xorriso - > toc_time_form & 1 ) | 2 ) ;
}
2010-05-15 18:48:10 +00:00
if ( image_blocks > track_size ) {
sprintf ( xorriso - > info_text ,
2024-03-19 18:59:06 +00:00
" Session %d bears ISO image size %.fs larger than track size %.fs " ,
session_no + 1 , ( double ) image_blocks , ( double ) track_size ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " ,
0 ) ;
image_blocks = track_size ;
}
}
2013-01-14 09:45:20 +00:00
if ( session_no > = num_sessions & & track_no = = 0 ) {
if ( ret < = 0 )
volume_id [ 0 ] = 0 ;
2024-03-19 18:59:06 +00:00
sprintf ( respt , " Incmp session: %3d , %9.f , %9.fs , %s \n " ,
session_no + 1 , ( double ) lba , ( double ) image_blocks ,
volume_id ) ;
2013-01-14 09:45:20 +00:00
} else if ( ret > 0 & & track_no = = 0 ) {
2024-03-19 18:59:06 +00:00
sprintf ( respt , " ISO session : %3d , %9.f , %9.fs , %s \n " ,
session_no + 1 , ( double ) lba , ( double ) image_blocks ,
volume_id ) ;
2010-05-15 18:48:10 +00:00
} else if ( ret > 0 ) {
2024-03-19 18:59:06 +00:00
sprintf ( respt , " ISO track : %3d , %9.f , %9.fs , %s \n " ,
track_count , ( double ) lba , ( double ) image_blocks , volume_id ) ;
2010-05-15 18:48:10 +00:00
} else if ( track_no = = 0 ) {
typetext = " Other session " ;
if ( flag & 4 )
typetext = " Session " ;
2024-03-19 18:59:06 +00:00
sprintf ( respt , " %13s: %3d , %9.f , %9.fs , \n " ,
typetext , session_no + 1 , ( double ) lba , ( double ) track_size ) ;
2010-05-15 18:48:10 +00:00
} else {
typetext = " Other track " ;
if ( flag & 4 )
typetext = " Track " ;
2024-03-19 18:59:06 +00:00
sprintf ( respt , " %13s: %3d , %9.f , %9.fs , \n " ,
typetext , track_count , ( double ) lba , ( double ) track_size ) ;
2010-05-15 18:48:10 +00:00
}
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
2019-07-13 15:30:47 +00:00
if ( is_data )
num_session_data + = track_size ;
else
num_session_other + = track_size ;
if ( track_no = = 0 )
first_track_start = lba ;
2010-05-15 18:48:10 +00:00
}
isoburn_toc_session_get_leadout_entry ( sessions [ session_no ] , & toc_entry ) ;
2024-03-19 18:59:06 +00:00
if ( toc_entry . extensions_valid & 8 ) {
lba = toc_entry . long_start_lba ;
} else if ( toc_entry . extensions_valid & 1 ) {
2010-05-15 18:48:10 +00:00
lba = toc_entry . start_lba ;
} else {
lba = burn_msf_to_lba ( toc_entry . pmin , toc_entry . psec , toc_entry . pframe ) ;
}
2019-07-13 15:30:47 +00:00
session_size = lba - first_track_start ;
if ( num_session_data > 0 & & num_session_other > 0 ) {
num_data + = num_session_data ;
other_data + = num_session_other ;
} else if ( is_data ) {
num_data + = session_size ;
} else {
other_data + = session_size ;
}
2010-05-15 18:48:10 +00:00
}
}
if ( xorriso - > request_to_abort )
{ ret = 1 ; goto ex ; }
2011-03-21 09:37:02 +00:00
Sfile_scale ( ( ( double ) num_data ) * 2048.0 , mem_text , 5 , 1e4 , 1 ) ;
2013-01-14 09:45:20 +00:00
sessions_seen = num_sessions + open_sessions ;
if ( open_sessions > 0 & & ! have_real_open_session )
sessions_seen - - ;
2024-03-19 18:59:06 +00:00
sprintf ( respt , " Media summary: %d session%s, %.f data blocks, %s data " ,
sessions_seen , ( sessions_seen = = 1 ? " " : " s " ) , ( double ) num_data ,
mem_text ) ;
2011-10-13 10:59:48 +00:00
if ( num_data_from_format )
num_free = 0 ;
else
num_free = isoburn_disc_available_space ( drive , NULL ) ;
2010-05-15 18:48:10 +00:00
Sfile_scale ( ( double ) num_free , mem_text , 5 , 1e4 , 1 ) ;
sprintf ( respt + strlen ( respt ) , " , %s free " , mem_text ) ;
sprintf ( respt + strlen ( respt ) , " \n " ) ;
Xorriso_toc_line ( xorriso , flag & 8 ) ;
2019-07-13 15:30:47 +00:00
if ( other_data > 0 ) {
2024-03-19 18:59:06 +00:00
sprintf ( respt , " Non-data blks: %.f \n " , ( double ) other_data ) ;
2019-07-13 15:30:47 +00:00
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
2010-05-15 18:48:10 +00:00
if ( s = = BURN_DISC_APPENDABLE & & nwa ! = 0 ) {
2024-03-19 18:59:06 +00:00
ret = isoburn_disc_track_lba_nwa_v2 ( drive , NULL , 0 , & lba , & nwa ) ;
2010-05-15 18:48:10 +00:00
if ( ret > 0 ) {
2024-03-19 18:59:06 +00:00
sprintf ( respt , " Media nwa : %.fs \n " , ( double ) nwa ) ;
2010-05-15 18:48:10 +00:00
if ( ! ( flag & 1 ) )
Xorriso_toc_line ( xorriso , flag & 8 ) ;
}
}
2013-01-14 09:45:20 +00:00
if ( profile_no = = 0x41 & & sessions_seen > = 300 ) {
2011-07-25 10:38:34 +00:00
sprintf ( xorriso - > info_text ,
2012-11-26 07:02:18 +00:00
" Sequential BD-R medium now contains %d sessions. It is likely to soon fail writing. " ,
2013-01-14 09:45:20 +00:00
sessions_seen ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
}
if ( have_real_open_session ) {
sprintf ( xorriso - > info_text , " Incomplete session encountered ! " ) ;
2011-07-25 10:38:34 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
}
2010-05-15 18:48:10 +00:00
ret = 1 ;
ex : ;
2019-09-08 10:30:52 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( disc ! = NULL )
isoburn_toc_disc_free ( disc ) ;
2010-05-15 18:48:10 +00:00
return ( ret ) ;
}
2011-07-27 21:14:49 +00:00
/* @param flag bit0= try to find 'meaningful' links for enumerated devices
*/
2010-05-15 18:48:10 +00:00
int Xorriso_show_devices ( struct XorrisO * xorriso , int flag )
{
2011-07-27 21:14:49 +00:00
char * adr = NULL , * link_adr = NULL , * adrpt ;
2011-05-08 17:47:43 +00:00
int i , j , max_dev_len = 1 , pad , ret ;
2010-05-15 18:48:10 +00:00
struct burn_drive_info * drive_list = NULL ;
unsigned int drive_count ;
char * respt , perms [ 8 ] ;
struct stat stbuf ;
2011-05-08 17:47:43 +00:00
Xorriso_alloc_meM ( adr , char , BURN_DRIVE_ADR_LEN ) ;
2011-07-28 19:51:21 +00:00
Xorriso_alloc_meM ( link_adr , char , BURN_DRIVE_ADR_LEN ) ;
2011-05-08 17:47:43 +00:00
2010-05-15 18:48:10 +00:00
sprintf ( xorriso - > info_text , " Beginning to scan for devices ... \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
burn_drive_clear_whitelist ( ) ;
while ( ! burn_drive_scan ( & drive_list , & drive_count ) ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
usleep ( 100000 ) ;
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2011-10-09 16:25:07 +00:00
if ( drive_count = = 0 ) {
2010-05-15 18:48:10 +00:00
/* >>> was a drive_list created at all ? */
/* >>> must it be freed ? */
sprintf ( xorriso - > info_text , " No drives found " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
2011-05-08 17:47:43 +00:00
{ ret = 0 ; goto ex ; }
2010-05-15 18:48:10 +00:00
}
sprintf ( xorriso - > info_text , " Full drive scan done \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " ----------------------------------------------------------------------------- \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
respt = xorriso - > result_line ;
2011-05-09 18:12:16 +00:00
for ( i = 0 ; i < ( int ) drive_count & & ! ( xorriso - > request_to_abort ) ; i + + ) {
2010-05-15 18:48:10 +00:00
if ( burn_drive_get_adr ( & ( drive_list [ i ] ) , adr ) < = 0 )
strcpy ( adr , " -get_adr_failed- " ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2011-07-27 21:14:49 +00:00
adrpt = adr ;
if ( flag & 1 ) {
2011-07-28 19:51:21 +00:00
ret = burn_lookup_device_link ( adr , link_adr , " /dev " , NULL , 0 , 0 ) ;
2011-07-27 21:14:49 +00:00
if ( ret < 0 )
goto ex ;
if ( ret = = 1 )
adrpt = link_adr ;
}
if ( ( int ) strlen ( adrpt ) > max_dev_len )
max_dev_len = strlen ( adrpt ) ;
2010-05-15 18:48:10 +00:00
}
2011-05-09 18:12:16 +00:00
for ( i = 0 ; i < ( int ) drive_count & & ! ( xorriso - > request_to_abort ) ; i + + ) {
2010-05-15 18:48:10 +00:00
if ( burn_drive_get_adr ( & ( drive_list [ i ] ) , adr ) < = 0 )
strcpy ( adr , " -get_adr_failed- " ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( stat ( adr , & stbuf ) = = - 1 ) {
sprintf ( perms , " errno=%d " , errno ) ;
} else {
strcpy ( perms , " ------ " ) ;
if ( stbuf . st_mode & S_IRUSR ) perms [ 0 ] = ' r ' ;
if ( stbuf . st_mode & S_IWUSR ) perms [ 1 ] = ' w ' ;
if ( stbuf . st_mode & S_IRGRP ) perms [ 2 ] = ' r ' ;
if ( stbuf . st_mode & S_IWGRP ) perms [ 3 ] = ' w ' ;
if ( stbuf . st_mode & S_IROTH ) perms [ 4 ] = ' r ' ;
if ( stbuf . st_mode & S_IWOTH ) perms [ 5 ] = ' w ' ;
}
2011-07-27 21:14:49 +00:00
adrpt = adr ;
if ( flag & 1 ) {
2011-07-28 19:51:21 +00:00
ret = burn_lookup_device_link ( adr , link_adr , " /dev " , NULL , 0 , 0 ) ;
2011-07-27 21:14:49 +00:00
if ( ret < 0 )
goto ex ;
if ( ret = = 1 )
adrpt = link_adr ;
}
sprintf ( respt , " %d -dev '%s' " , i , adrpt ) ;
pad = max_dev_len - strlen ( adrpt ) ;
2010-05-15 18:48:10 +00:00
if ( pad > 0 )
for ( j = 0 ; j < pad ; j + + )
strcat ( respt , " " ) ;
sprintf ( respt + strlen ( respt ) , " %s : '%-8.8s' '%s' \n " ,
perms , drive_list [ i ] . vendor , drive_list [ i ] . product ) ;
Xorriso_result ( xorriso , 0 ) ;
}
sprintf ( xorriso - > info_text , " ----------------------------------------------------------------------------- \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
burn_drive_info_free ( drive_list ) ;
2011-05-08 17:47:43 +00:00
ret = 1 ;
ex : ;
2011-07-27 21:14:49 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2011-05-08 17:47:43 +00:00
Xorriso_free_meM ( adr ) ;
2011-07-28 19:51:21 +00:00
Xorriso_free_meM ( link_adr ) ;
2011-05-08 17:47:43 +00:00
return ( ret ) ;
2010-05-15 18:48:10 +00:00
}
int Xorriso_tell_media_space ( struct XorrisO * xorriso ,
2024-03-19 20:54:14 +00:00
off_t * media_space , off_t * free_space , int flag )
2010-05-15 18:48:10 +00:00
{
2024-03-19 20:54:14 +00:00
off_t ret ;
2010-05-15 18:48:10 +00:00
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
struct burn_write_opts * burn_options ;
( * free_space ) = ( * media_space ) = 0 ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to -tell_media_space " , 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
ret = Xorriso_make_write_options ( xorriso , drive , & burn_options , 0 ) ;
if ( ret < = 0 )
return ( - 1 ) ;
( * free_space ) = ( * media_space ) =
isoburn_disc_available_space ( drive , burn_options ) / ( off_t ) 2048 ;
burn_write_opts_free ( burn_options ) ;
2012-03-03 13:39:50 +00:00
if ( Xorriso_change_is_pending ( xorriso , 0 ) ) {
2010-05-15 18:48:10 +00:00
ret = Xorriso_write_session ( xorriso , 1 ) ;
2017-02-13 14:52:36 +00:00
if ( ret > 0 ) {
2010-05-15 18:48:10 +00:00
( * free_space ) - = ret ;
2017-02-13 14:52:36 +00:00
} else {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 0 ) ;
}
2010-05-15 18:48:10 +00:00
}
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
/* @return <=0 error, 1 success
*/
int Xorriso_list_formats ( struct XorrisO * xorriso , int flag )
{
2010-09-24 11:09:09 +00:00
int ret , i , status , num_formats , profile_no , type , alloc_blocks , free_blocks ;
2010-05-15 18:48:10 +00:00
off_t size ;
unsigned dummy ;
char status_text [ 80 ] , profile_name [ 90 ] , * respt ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
respt = xorriso - > result_line ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to obtain format descriptor list " , 1 | 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
if ( ret = = 2 )
goto ex ;
ret = burn_disc_get_formats ( drive , & status , & size , & dummy ,
& num_formats ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text , " Cannot obtain format list info " ) ;
2014-03-06 07:59:17 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
2010-05-15 18:48:10 +00:00
ret = 0 ; goto ex ;
}
ret = Xorriso_toc ( xorriso , 3 ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret < = 0 )
goto ex ;
if ( status = = BURN_FORMAT_IS_UNFORMATTED )
sprintf ( status_text , " unformatted, up to %.1f MiB " ,
( ( double ) size ) / 1024.0 / 1024.0 ) ;
else if ( status = = BURN_FORMAT_IS_FORMATTED ) {
if ( profile_no = = 0x12 | | profile_no = = 0x13 | | profile_no = = 0x1a | |
profile_no = = 0x43 )
sprintf ( status_text , " formatted, with %.1f MiB " ,
( ( double ) size ) / 1024.0 / 1024.0 ) ;
else
sprintf ( status_text , " written, with %.1f MiB " ,
( ( double ) size ) / 1024.0 / 1024.0 ) ;
} else if ( status = = BURN_FORMAT_IS_UNKNOWN ) {
if ( profile_no > 0 )
sprintf ( status_text , " intermediate or unknown " ) ;
else
sprintf ( status_text , " no media or unknown media " ) ;
} else
sprintf ( status_text , " illegal status according to MMC-5 " ) ;
sprintf ( respt , " Format status: %s \n " , status_text ) ;
Xorriso_result ( xorriso , 0 ) ;
2010-09-24 11:09:09 +00:00
ret = burn_disc_get_bd_spare_info ( drive , & alloc_blocks , & free_blocks , 0 ) ;
if ( ret = = 1 ) {
sprintf ( respt , " BD Spare Area: %d blocks consumed, %d blocks available \n " ,
alloc_blocks - free_blocks , free_blocks ) ;
Xorriso_result ( xorriso , 0 ) ;
}
2010-05-15 18:48:10 +00:00
for ( i = 0 ; i < num_formats ; i + + ) {
ret = burn_disc_get_format_descr ( drive , i , & type , & size , & dummy ) ;
if ( ret < = 0 )
continue ;
sprintf ( respt , " Format idx %-2d: %2.2Xh , %.fs , %.1f MiB \n " ,
i , type , ( ( double ) size ) / 2048.0 , ( ( double ) size ) / 1024.0 / 1024.0 ) ;
Xorriso_result ( xorriso , 0 ) ;
}
ret = 1 ;
ex : ;
return ( ret ) ;
}
2014-01-09 21:53:28 +00:00
/* @param flag bit0= This is write speed. Consider the existence of
combo drives ( e . g . DVD - ROM / CD - RW or BD - ROM / DVD + - RW )
*/
2011-07-12 13:56:36 +00:00
int Xorriso_choose_speed_factor ( struct XorrisO * xorriso ,
int speed , int profile ,
2014-01-09 21:53:28 +00:00
struct burn_drive * drive ,
2011-07-12 13:56:36 +00:00
double * speed_factor , char * * speed_unit ,
int flag )
{
2014-01-09 21:53:28 +00:00
int i , no_dvd_read = 1 , no_dvd_write = 1 , no_bd_read = 1 , no_bd_write = 1 , ret ;
int num_profiles , profiles [ 64 ] ;
char is_current [ 64 ] ;
2011-07-12 13:56:36 +00:00
* speed_unit = " D " ;
* speed_factor = 1385000.0 ;
2014-01-09 21:53:28 +00:00
if ( ( flag & 1 ) | | profile = = 0x00 ) {
ret = burn_drive_get_all_profiles ( drive , & num_profiles ,
profiles , is_current ) ;
if ( ret > 0 ) {
for ( i = 0 ; i < num_profiles ; i + + ) {
if ( profiles [ i ] > 0x10 & & profiles [ i ] < 0x30 )
no_dvd_read = no_dvd_write = 0 ;
else if ( profiles [ i ] = = 0x10 )
no_dvd_read = 0 ;
else if ( profiles [ i ] > 0x40 & & profiles [ i ] < = 0x43 )
no_bd_read = no_bd_write = 0 ;
else if ( profiles [ i ] = = 0x40 )
no_bd_read = 0 ;
}
}
2011-07-12 13:56:36 +00:00
}
2014-01-09 21:53:28 +00:00
if ( profile = = 0x00 ) { /* No medium loaded, guess from profile list */
if ( flag & 1 ) {
if ( no_bd_write & & no_dvd_write )
* speed_unit = " C " ;
else if ( ! no_bd_write )
* speed_unit = " B " ;
} else {
if ( no_bd_read & & no_dvd_read )
* speed_unit = " C " ;
else if ( ! no_bd_read )
* speed_unit = " B " ;
}
} else if ( ( profile > 0x00 & & profile < = 0x0a ) | |
2014-03-04 16:41:19 +00:00
( ( ( no_dvd_write & & no_bd_write ) & & ( flag & 1 ) ) ) ) {
2011-07-12 13:56:36 +00:00
* speed_unit = " C " ;
2014-01-09 21:53:28 +00:00
} else if ( ( profile > = 0x40 & & profile < = 0x43 ) & &
! ( no_bd_write & & ( flag & 1 ) ) ) {
2011-07-12 13:56:36 +00:00
* speed_unit = " B " ;
}
2014-01-09 21:53:28 +00:00
if ( ( * speed_unit ) [ 0 ] = = ' C ' )
* speed_factor = 75.0 * 2352.0 ;
else if ( ( * speed_unit ) [ 0 ] = = ' B ' )
* speed_factor = 4495625.0 ;
2011-07-12 13:56:36 +00:00
return ( 1 ) ;
}
2014-01-09 21:53:28 +00:00
/* For sorting the int *speeds array
*/
int Xorriso__reverse_int_cmp ( const void * a , const void * b )
{
int diff ;
diff = * ( ( int * ) a ) - * ( ( int * ) b ) ;
if ( diff < 0 )
return ( 1 ) ;
else if ( diff > 0 )
return ( - 1 ) ;
return ( 0 ) ;
}
2013-10-08 17:58:09 +00:00
/* @flag bit0= do not issue TOC
bit1 = Report about outdev ( else indev )
bit2 = Report about write speed ( else read speed )
@ return < = 0 error , 1 success
2011-07-04 09:29:00 +00:00
*/
2013-10-08 17:58:09 +00:00
int Xorriso_list_speeds_sub ( struct XorrisO * xorriso , int flag )
2011-07-04 09:29:00 +00:00
{
2014-01-09 21:53:28 +00:00
int ret , high = - 1 , low = 0x7fffffff , is_cd = 0 , i , speed , profile = 0 ;
int inout_flag , prev_speed = - 1 , speed_count = 0 ;
int * speeds = NULL ;
2011-07-04 09:29:00 +00:00
char * respt , * speed_unit = " D " ;
double speed_factor = 1385000.0 , cd_factor = 75.0 * 2352 ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
struct burn_speed_descriptor * speed_list = NULL , * item , * other ;
respt = xorriso - > result_line ;
2013-10-08 17:58:09 +00:00
inout_flag = ( flag & 2 ) ;
if ( inout_flag & & xorriso - > out_drive_handle = = NULL )
inout_flag = 0 ;
else if ( xorriso - > in_drive_handle = = NULL )
inout_flag = 2 ;
2011-07-04 09:29:00 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
2013-10-08 17:58:09 +00:00
" on attempt to obtain speed descriptor list " ,
1 | inout_flag ) ;
2011-07-04 09:29:00 +00:00
if ( ret < = 0 )
return ( 0 ) ;
if ( ret = = 2 )
goto ex ;
ret = burn_drive_get_speedlist ( drive , & speed_list ) ;
2011-07-12 09:21:28 +00:00
if ( ret < 0 ) {
2011-07-04 09:29:00 +00:00
sprintf ( xorriso - > info_text , " Cannot obtain speed list info " ) ;
2011-07-12 09:21:28 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
2011-07-04 09:29:00 +00:00
ret = 0 ; goto ex ;
}
2013-10-08 17:58:09 +00:00
if ( ! ( flag & 1 ) ) {
ret = Xorriso_toc ( xorriso , 1 | inout_flag ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text ,
" Cannot obtain overview of drive and media content " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
ret = 0 ; goto ex ;
}
2011-07-12 13:56:36 +00:00
}
2011-07-04 09:29:00 +00:00
2014-01-09 21:53:28 +00:00
speed_count = 0 ;
for ( item = speed_list ; item ! = NULL ; item = item - > next )
speed_count + + ;
if ( speed_count > 0 )
Xorriso_alloc_meM ( speeds , int , speed_count ) ;
speed_count = 0 ;
for ( item = speed_list ; item ! = NULL ; item = item - > next ) {
2011-07-24 19:34:52 +00:00
2013-10-08 17:58:09 +00:00
sprintf ( xorriso - > info_text ,
" read_speed= %5dk , write_speed= %5dk , source= %d " ,
item - > read_speed , item - > write_speed , item - > source ) ;
2011-07-24 19:34:52 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " DEBUG " , 0 ) ;
2011-07-04 09:29:00 +00:00
if ( item - > source = = 1 ) {
/* CD mode page 2Ah : report only if not same speed by GET PERFORMANCE */
2013-10-08 17:58:09 +00:00
if ( ! ( flag & 4 ) )
2014-01-09 21:53:28 +00:00
continue ; /* 2Ah only tells write speed */
2011-07-04 09:29:00 +00:00
for ( other = speed_list ; other ! = NULL ; other = other - > next )
if ( other - > source = = 2 & & item - > write_speed = = other - > write_speed )
break ;
if ( other ! = NULL )
continue ;
}
2013-10-08 17:58:09 +00:00
if ( flag & 4 ) {
2014-01-09 21:53:28 +00:00
if ( item - > write_speed < = 0 )
continue ;
2013-10-08 17:58:09 +00:00
speed = item - > write_speed ;
} else {
2014-01-09 21:53:28 +00:00
if ( item - > read_speed < = 0 )
continue ;
2013-10-08 17:58:09 +00:00
speed = item - > read_speed ;
}
2014-01-09 21:53:28 +00:00
speeds [ speed_count ] = speed ;
if ( item - > profile_loaded > 0 )
profile = item - > profile_loaded ;
speed_count + + ;
}
if ( speed_count > 0 )
qsort ( speeds , ( size_t ) speed_count , sizeof ( int ) , Xorriso__reverse_int_cmp ) ;
if ( profile > = 0x08 & & profile < = 0x0a )
is_cd = profile ;
for ( i = 0 ; i < speed_count ; i + + ) {
speed = speeds [ i ] ;
2013-10-29 12:36:09 +00:00
if ( speed = = prev_speed )
continue ;
prev_speed = speed ;
2014-01-09 21:53:28 +00:00
if ( flag & 4 )
sprintf ( respt , " Write speed : " ) ;
else
sprintf ( respt , " Read speed : " ) ;
Xorriso_choose_speed_factor ( xorriso , speed , profile , drive ,
& speed_factor , & speed_unit , ! ! ( flag & 4 ) ) ;
2011-07-04 09:29:00 +00:00
sprintf ( respt + strlen ( respt ) , " %5dk , %4.1fx%s \n " ,
2013-10-08 17:58:09 +00:00
speed , ( ( double ) speed ) * 1000.0 / speed_factor , speed_unit ) ;
2011-07-04 09:29:00 +00:00
Xorriso_result ( xorriso , 0 ) ;
2013-10-08 17:58:09 +00:00
if ( speed > high )
high = speed ;
if ( speed < low )
low = speed ;
2011-07-04 09:29:00 +00:00
}
2013-10-08 17:58:09 +00:00
/* Maybe there is ATIP info (about write speed only) */
if ( is_cd & & ( flag & 4 ) ) {
2011-07-04 09:29:00 +00:00
ret = burn_disc_read_atip ( drive ) ;
if ( ret < 0 )
goto ex ;
if ( ret > 0 ) {
2011-07-12 09:21:28 +00:00
for ( i = 0 ; i < 2 ; i + + ) {
if ( i = = 0 )
ret = burn_drive_get_min_write_speed ( drive ) ;
else
ret = burn_drive_get_write_speed ( drive ) ;
if ( ret > 0 ) {
if ( ret < low | | ( i = = 0 & & ret ! = low ) ) {
sprintf ( respt , " Write speed l: " ) ;
sprintf ( respt + strlen ( respt ) , " %5dk , %4.1fx%s \n " ,
ret , ( ( double ) ret ) * 1000.0 / cd_factor , " C " ) ;
Xorriso_result ( xorriso , 0 ) ;
low = ret ;
}
if ( ret > high | | ( i = = 1 & & ret ! = high ) ) {
sprintf ( respt , " Write speed h: " ) ;
sprintf ( respt + strlen ( respt ) , " %5dk , %4.1fx%s \n " ,
ret , ( ( double ) ret ) * 1000.0 / cd_factor , " C " ) ;
Xorriso_result ( xorriso , 0 ) ;
high = ret ;
}
}
}
2011-07-04 09:29:00 +00:00
}
}
if ( high > - 1 ) {
2014-01-09 21:53:28 +00:00
Xorriso_choose_speed_factor ( xorriso , low , profile , drive ,
& speed_factor , & speed_unit , ! ! ( flag & 4 ) ) ;
2013-10-08 17:58:09 +00:00
if ( flag & 4 )
sprintf ( respt , " Write speed L: " ) ;
else
sprintf ( respt , " Read speed L : " ) ;
2011-07-04 09:29:00 +00:00
sprintf ( respt + strlen ( respt ) , " %5dk , %4.1fx%s \n " ,
low , ( ( double ) low ) * 1000.0 / speed_factor , speed_unit ) ;
Xorriso_result ( xorriso , 0 ) ;
2014-01-09 21:53:28 +00:00
Xorriso_choose_speed_factor ( xorriso , low , profile , drive ,
& speed_factor , & speed_unit , ! ! ( flag & 4 ) ) ;
2013-10-08 17:58:09 +00:00
if ( flag & 4 )
sprintf ( respt , " Write speed H: " ) ;
else
sprintf ( respt , " Read speed H : " ) ;
2011-07-04 09:29:00 +00:00
sprintf ( respt + strlen ( respt ) , " %5dk , %4.1fx%s \n " ,
high , ( ( double ) high ) * 1000.0 / speed_factor , speed_unit ) ;
Xorriso_result ( xorriso , 0 ) ;
2013-03-06 16:49:32 +00:00
ret = burn_drive_get_best_speed ( drive , 0 , & item , 2 ) ;
2013-10-08 17:58:09 +00:00
if ( ret > 0 & & item ! = NULL & & ( flag & 4 ) )
2013-03-06 16:49:32 +00:00
if ( item - > write_speed ! = high ) {
sprintf ( respt , " Write speed 0: %5dk , %4.1fx%s \n " ,
item - > write_speed ,
( ( double ) item - > write_speed ) * 1000.0 / speed_factor , speed_unit ) ;
Xorriso_result ( xorriso , 0 ) ;
}
2011-07-12 09:21:28 +00:00
} else {
sprintf ( xorriso - > info_text ,
2013-10-08 17:58:09 +00:00
" Could not get any %s speed information from drive " ,
( flag & 4 ) ? " write " : " read " ) ;
2014-01-09 15:54:48 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
ret = 2 ; goto ex ;
2011-07-04 09:29:00 +00:00
}
ret = 1 ;
ex : ;
if ( speed_list ! = NULL )
burn_drive_free_speedlist ( & speed_list ) ;
2014-01-09 21:53:28 +00:00
Xorriso_free_meM ( speeds ) ;
2011-07-04 09:29:00 +00:00
return ( ret ) ;
}
2013-10-08 17:58:09 +00:00
int Xorriso_list_speeds ( struct XorrisO * xorriso , int flag )
{
int ret ;
if ( xorriso - > out_drive_handle = = NULL & & xorriso - > in_drive_handle = = NULL ) {
Xorriso_msgs_submit ( xorriso , 0 ,
2015-09-20 12:51:53 +00:00
" No drive acquired on attempt to list speeds " , 0 , " FAILURE " , 0 ) ;
2013-10-08 17:58:09 +00:00
return ( 0 ) ;
}
if ( xorriso - > in_drive_handle ! = NULL ) {
ret = Xorriso_list_speeds_sub ( xorriso , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
}
if ( xorriso - > out_drive_handle ! = NULL & &
xorriso - > out_drive_handle ! = xorriso - > in_drive_handle ) {
ret = Xorriso_list_speeds_sub ( xorriso , 2 ) ;
if ( ret < = 0 )
return ( ret ) ;
}
if ( xorriso - > out_drive_handle ! = NULL ) {
ret = Xorriso_list_speeds_sub ( xorriso , 1 | 2 | 4 ) ;
if ( ret < = 0 )
return ( ret ) ;
}
return ( 1 ) ;
}
2010-05-15 18:48:10 +00:00
/* @param flag bit0= cdrecord style
bit1 = obtain outdrive , else indrive
@ return < = 0 error , 1 success
*/
int Xorriso_list_profiles ( struct XorrisO * xorriso , int flag )
{
int ret , i ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
int num_profiles , profiles [ 64 ] ;
char is_current [ 64 ] , profile_name [ 90 ] , * respt ;
respt = xorriso - > result_line ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to obtain profile list " , 1 | ( flag & 2 ) ) ;
if ( ret < = 0 )
return ( 0 ) ;
burn_drive_get_all_profiles ( drive , & num_profiles , profiles , is_current ) ;
for ( i = 0 ; i < num_profiles ; i + + ) {
ret = burn_obtain_profile_name ( profiles [ i ] , profile_name ) ;
if ( ret < = 0 )
strcpy ( profile_name , " unknown " ) ;
sprintf ( respt , " %s 0x%4.4X (%s)%s \n " ,
flag & 1 ? " Profile: " : " Profile : " ,
( unsigned int ) profiles [ i ] ,
profile_name , is_current [ i ] ? " (current) " : " " ) ;
Xorriso_result ( xorriso , 0 ) ;
}
return ( 1 ) ;
}
/* @param flag bit0= -inq
bit1 = - checkdrive
*/
int Xorriso_atip ( struct XorrisO * xorriso , int flag )
{
2017-02-13 14:52:36 +00:00
int ret , profile_number = 0 , is_bdr_pow = 0 ;
2011-10-26 08:52:37 +00:00
int num_profiles = 0 , profiles [ 64 ] , i , can_write = 0 , pf , no_medium = 0 ;
2011-10-25 16:01:11 +00:00
char is_current [ 64 ] ;
2010-05-15 18:48:10 +00:00
char * respt , profile_name [ 80 ] ;
double x_speed_max , x_speed_min = - 1.0 ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
enum burn_disc_status s ;
char * manuf = NULL , * media_code1 = NULL , * media_code2 = NULL ;
char * book_type = NULL , * product_id = NULL ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to print drive and media info " , 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
respt = xorriso - > result_line ;
sprintf ( respt , " Device type : " ) ;
ret = burn_drive_get_drive_role ( drive ) ;
if ( ret = = 0 )
sprintf ( respt + strlen ( respt ) , " %s \n " , " Emulated (null-drive) " ) ;
else if ( ret = = 2 )
sprintf ( respt + strlen ( respt ) , " %s \n " ,
" Emulated (stdio-drive, 2k random read-write) " ) ;
else if ( ret = = 3 )
sprintf ( respt + strlen ( respt ) , " %s \n " ,
" Emulated (stdio-drive, sequential write-only) " ) ;
2011-03-21 09:37:02 +00:00
else if ( ret = = 4 )
sprintf ( respt + strlen ( respt ) , " %s \n " ,
" Emulated (stdio-drive, 2k random read-only) " ) ;
else if ( ret = = 5 )
sprintf ( respt + strlen ( respt ) , " %s \n " ,
" Emulated (stdio-drive, 2k random write-only) " ) ;
2010-05-15 18:48:10 +00:00
else if ( ret ! = 1 )
sprintf ( respt + strlen ( respt ) , " %s \n " , " Emulated (stdio-drive) " ) ;
else
sprintf ( respt + strlen ( respt ) , " %s \n " , " Removable CD-ROM " ) ;
sprintf ( respt + strlen ( respt ) , " Vendor_info : '%s' \n " , dinfo - > vendor ) ;
sprintf ( respt + strlen ( respt ) , " Identifikation : '%s' \n " , dinfo - > product ) ;
sprintf ( respt + strlen ( respt ) , " Revision : '%s' \n " , dinfo - > revision ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( flag & 1 )
return ( 1 ) ;
2011-10-25 16:01:11 +00:00
/* Do not report "Supported modes: SAO TAO" with -ROM drives */
burn_drive_get_all_profiles ( drive , & num_profiles , profiles , is_current ) ;
if ( num_profiles > 0 ) {
for ( i = 0 ; i < num_profiles ; i + + ) {
pf = profiles [ i ] ;
if ( pf = = 0x09 | | pf = = 0x0a | | pf = = 0x11 | | pf = = 0x12 | | pf = = 0x13 | |
pf = = 0x14 | | pf = = 0x15 | | pf = = 0x1a | | pf = = 0x1b | | pf = = 0x2b | |
pf = = 0x41 | | pf = = 0x43 | | pf = = 0xffff ) {
can_write = 1 ;
break ;
}
}
} else
can_write = 1 ;
if ( can_write ) {
sprintf ( respt , " Driver flags : BURNFREE \n " ) ;
sprintf ( respt + strlen ( respt ) , " Supported modes: SAO TAO \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
} else if ( flag & 2 ) {
sprintf ( xorriso - > info_text , " Not a CD/DVD/BD recorder " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
}
2010-05-15 18:48:10 +00:00
if ( flag & 2 )
return ( 1 ) ;
2017-02-13 14:52:36 +00:00
is_bdr_pow = burn_drive_get_bd_r_pow ( drive ) ;
2010-05-15 18:48:10 +00:00
s = burn_disc_get_status ( drive ) ;
ret = burn_disc_get_profile ( drive , & profile_number , profile_name ) ;
if ( ret < = 0 ) {
profile_number = 0 ;
strcpy ( profile_name , " -unidentified- " ) ;
}
if ( s ! = BURN_DISC_UNSUITABLE ) {
ret = burn_disc_read_atip ( drive ) ;
if ( ret > 0 ) {
ret = burn_drive_get_min_write_speed ( drive ) ;
x_speed_min = ( ( double ) ret ) / 176.4 ;
}
}
if ( s = = BURN_DISC_EMPTY ) {
sprintf ( respt , " Current: none \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
2011-10-26 08:52:37 +00:00
sprintf ( xorriso - > info_text , " No recognizable medium found in drive " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " SORRY " , 0 ) ;
no_medium = 1 ;
2010-05-15 18:48:10 +00:00
} else
2017-02-13 14:52:36 +00:00
sprintf ( respt , " Current: %s%s \n " , profile_name ,
is_bdr_pow ? " , Pseudo Overwrite formatted " : " " ) ;
2010-05-15 18:48:10 +00:00
Xorriso_result ( xorriso , 1 ) ;
Xorriso_list_profiles ( xorriso , 1 | 2 ) ;
2011-10-26 08:52:37 +00:00
if ( no_medium )
return ( 1 ) ;
2010-05-15 18:48:10 +00:00
if ( strstr ( profile_name , " BD " ) = = profile_name ) {
printf ( " Mounted Media: %2.2Xh, %s \n " , profile_number , profile_name ) ;
} else if ( strstr ( profile_name , " DVD " ) = = profile_name ) {
sprintf ( respt , " book type: %s (emulated booktype) \n " , profile_name ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( profile_number = = 0x13 ) {
sprintf ( respt , " xorriso: message for sdvdbackup: \" (growisofs mode Restricted Overwrite) \" \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
}
} else {
sprintf ( respt , " ATIP info from disk: \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( burn_disc_erasable ( drive ) )
sprintf ( respt , " Is erasable \n " ) ;
else
sprintf ( respt , " Is not erasable \n " ) ;
Xorriso_result ( xorriso , 1 ) ;
{ int start_lba , end_lba , min , sec , fr ;
ret = burn_drive_get_start_end_lba ( drive , & start_lba , & end_lba , 0 ) ;
if ( ret > 0 ) {
burn_lba_to_msf ( start_lba , & min , & sec , & fr ) ;
sprintf ( respt , " ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d) \n " ,
start_lba , min , sec , fr ) ;
Xorriso_result ( xorriso , 1 ) ;
burn_lba_to_msf ( end_lba , & min , & sec , & fr ) ;
sprintf ( respt , " ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d) \n " ,
end_lba , min , sec , fr ) ;
Xorriso_result ( xorriso , 1 ) ;
}
}
ret = burn_drive_get_write_speed ( drive ) ;
x_speed_max = ( ( double ) ret ) / 176.4 ;
if ( x_speed_min < 0 )
x_speed_min = x_speed_max ;
sprintf ( respt ,
" 1T speed low: %.f 1T speed high: %.f \n " , x_speed_min , x_speed_max ) ;
Xorriso_result ( xorriso , 1 ) ;
}
ret = burn_disc_get_media_id ( drive , & product_id , & media_code1 , & media_code2 ,
& book_type , 0 ) ;
if ( ret > 0 & & media_code1 ! = NULL & & media_code2 ! = NULL )
manuf = burn_guess_manufacturer ( profile_number , media_code1 , media_code2 , 0 ) ;
if ( product_id ! = NULL ) {
sprintf ( respt , " Product Id: %s \n " , product_id ) ;
Xorriso_result ( xorriso , 1 ) ;
}
if ( manuf ! = NULL ) {
sprintf ( respt , " Producer: %s \n " , manuf ) ;
Xorriso_result ( xorriso , 1 ) ;
}
2024-03-17 15:26:38 +00:00
if ( manuf ! = NULL & & ( profile_number = = 0x09 | | profile_number = = 0x0a ) ) {
2010-05-15 18:48:10 +00:00
sprintf ( respt , " Manufacturer: %s \n " , manuf ) ;
Xorriso_result ( xorriso , 1 ) ;
} else if ( product_id ! = NULL & & media_code1 ! = NULL & & media_code2 ! = NULL ) {
free ( product_id ) ;
free ( media_code1 ) ;
free ( media_code2 ) ;
if ( book_type ! = NULL )
free ( book_type ) ;
product_id = media_code1 = media_code2 = book_type = NULL ;
ret = burn_disc_get_media_id ( drive , & product_id , & media_code1 , & media_code2 ,
& book_type , 1 ) ;
if ( ret > 0 ) {
sprintf ( respt , " Manufacturer: '%s' \n " , media_code1 ) ;
Xorriso_result ( xorriso , 1 ) ;
if ( media_code2 [ 0 ] ) {
sprintf ( respt , " Media type: '%s' \n " , media_code2 ) ;
Xorriso_result ( xorriso , 1 ) ;
}
}
}
if ( manuf ! = NULL )
free ( manuf ) ;
if ( media_code1 ! = NULL )
free ( media_code1 ) ;
if ( media_code2 ! = NULL )
free ( media_code2 ) ;
if ( book_type ! = NULL )
free ( book_type ) ;
if ( product_id ! = NULL )
free ( product_id ) ;
return ( 1 ) ;
}
/* @param flag bit1= outdev rather than indev
@ return < 0 error , 0 = no profile to see , 1 = ok , 2 = ok , is CD profile
3 = ok , is BD profile
*/
int Xorriso_get_profile ( struct XorrisO * xorriso , int * profile_number ,
char profile_name [ 80 ] , int flag )
{
int ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
* profile_number = 0 ;
profile_name [ 0 ] = 0 ;
if ( ( ( flag & 2 ) & & xorriso - > out_drive_handle = = NULL ) | |
( ( ! ( flag & 2 ) ) & & xorriso - > in_drive_handle = = NULL ) )
return ( 0 ) ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to determine media type " , flag & 2 ) ;
if ( ret < = 0 )
return ( 0 ) ;
ret = burn_disc_get_profile ( drive , profile_number , profile_name ) ;
if ( ret < = 0 )
return ( ret ) ;
if ( * profile_number = = 0x08 | | * profile_number = = 0x09 | | * profile_number = = 0x0a )
return ( 2 ) ;
if ( * profile_number = = 0x40 | | * profile_number = = 0x41 | |
* profile_number = = 0x42 | | * profile_number = = 0x43 )
return ( 3 ) ;
return ( 0 ) ;
}
/* @param flag bit0= grow_overwriteable_iso
bit1 = obtain info from outdev
bit2 = no need to obtain msc2 ( NWA )
*/
2024-03-20 11:45:09 +00:00
int Xorriso_msinfo ( struct XorrisO * xorriso , off_t * msc1 , off_t * msc2 , int flag )
2010-05-15 18:48:10 +00:00
{
2024-03-20 11:45:09 +00:00
int ret , is_bdr_pow = 0 ;
off_t dummy ;
2010-05-15 18:48:10 +00:00
struct burn_drive * drive ;
struct burn_drive_info * dinfo ;
enum burn_disc_status disc_state ;
* msc1 = * msc2 = - 1 ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to obtain msinfo " , flag & 2 ) ;
if ( ret < = 0 )
return ( ret ) ;
2017-02-13 14:52:36 +00:00
is_bdr_pow = burn_drive_get_bd_r_pow ( drive ) ;
if ( is_bdr_pow ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text ,
" %s medium is unsuitably POW formatted BD-R. Cannot obtain -msinfo. " ,
( flag & 2 ) ? " Output " : " Input " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( 0 ) ;
}
2010-05-15 18:48:10 +00:00
if ( flag & 1 )
disc_state = isoburn_disc_get_status ( drive ) ;
else
disc_state = burn_disc_get_status ( drive ) ;
if ( disc_state ! = BURN_DISC_APPENDABLE & &
! ( disc_state = = BURN_DISC_FULL & & ( flag & 4 ) ) ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ! ( flag & 4 ) ) {
sprintf ( xorriso - > info_text ,
2011-11-02 14:21:29 +00:00
" %s medium is not appendable. Cannot obtain -msinfo. " ,
2010-05-15 18:48:10 +00:00
( flag & 2 ) ? " Output " : " Input " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
}
return ( 0 ) ;
}
2024-03-20 11:45:09 +00:00
ret = isoburn_disc_get_msc1_v2 ( drive , msc1 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " Cannot obtain address of most recent session " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( 0 ) ;
}
if ( flag & 4 )
return ( 1 ) ;
2024-03-20 11:45:09 +00:00
ret = isoburn_disc_track_lba_nwa_v2 ( drive , NULL , 0 , & dummy , msc2 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " Cannot obtain next writeable address on media " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( 0 ) ;
}
return ( 1 ) ;
}
/* @param flag bit0=input drive
bit1 = output drive
bit2 = wake up rather than calm down
*/
int Xorriso_drive_snooze ( struct XorrisO * xorriso , int flag )
{
int in_is_out_too , ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
in_is_out_too = ( xorriso - > in_drive_handle = = xorriso - > out_drive_handle ) ;
if ( ( flag & 1 ) & & xorriso - > in_drive_handle ! = NULL ) {
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to calm drive " , 0 ) ;
burn_drive_snooze ( drive , ! ! ( flag & 4 ) ) ;
if ( in_is_out_too )
{ ret = 1 ; goto ex ; }
}
if ( ( flag & 2 ) & & xorriso - > out_drive_handle ! = NULL ) {
Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to calm drive " , 2 ) ;
burn_drive_snooze ( drive , ! ! ( flag & 4 ) ) ;
}
ret = 1 ;
ex : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( ret ) ;
}
/* @param flag bit0= enable SCSI command logging to stderr */
int Xorriso_scsi_log ( struct XorrisO * xorriso , int flag )
{
if ( flag = = 0 )
burn_set_scsi_logging ( 0 ) ;
else
burn_set_scsi_logging ( 2 | 4 ) ;
return ( 1 ) ;
}
2010-11-03 08:11:45 +00:00
2010-05-15 18:48:10 +00:00
int Xorriso_check_md5_range ( struct XorrisO * xorriso , off_t start_lba ,
off_t end_lba , char md5 [ 16 ] , int flag )
{
2020-08-26 14:29:40 +00:00
int ret , us_corr = 0 ;
2010-05-15 18:48:10 +00:00
struct burn_drive_info * dinfo = NULL ;
struct burn_drive * drive = NULL ;
2020-08-26 14:29:40 +00:00
off_t pos , data_count , to_read , slowdown_count = 0 ;
2011-05-08 17:47:43 +00:00
char * data = NULL , data_md5 [ 16 ] ;
2010-05-15 18:48:10 +00:00
void * ctx = NULL ;
2020-08-26 14:29:40 +00:00
struct timeval prev_time ;
2010-05-15 18:48:10 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to check session MD5 checksum " , 0 ) ;
if ( ret < = 0 )
goto ex ;
2011-05-08 17:47:43 +00:00
Xorriso_alloc_meM ( data , char , 64 * 1024 ) ;
2010-05-15 18:48:10 +00:00
ret = iso_md5_start ( & ctx ) ;
if ( ret < = 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
goto ex ;
}
2020-08-26 14:29:40 +00:00
if ( xorriso - > read_speed_force > 0 ) /* initialize forced speed limit */
burn_nominal_slowdown ( xorriso - > read_speed_force , xorriso - > read_speed_corr ,
& prev_time , & us_corr , ( off_t ) 0 , 1 ) ;
Xorriso_set_speed ( xorriso , drive , xorriso - > read_speed , 0 , 1 ) ;
2013-10-08 17:58:09 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2010-05-15 18:48:10 +00:00
for ( pos = start_lba ; pos < end_lba ; pos + = 32 ) {
to_read = 32 ;
if ( pos + to_read > end_lba )
to_read = end_lba - pos ;
ret = burn_read_data ( drive , pos * ( off_t ) 2048 , data ,
to_read * ( off_t ) 2048 , & data_count , 0 ) ;
if ( ret < = 0 )
goto ex ;
iso_md5_compute ( ctx , data , ( int ) data_count ) ;
2020-08-26 14:29:40 +00:00
if ( xorriso - > read_speed_force > 0 & & pos + to_read < = end_lba ) {
slowdown_count + = data_count ;
if ( slowdown_count > = 128 * 1024 ) {
burn_nominal_slowdown ( xorriso - > read_speed_force ,
xorriso - > read_speed_corr ,
& prev_time , & us_corr , slowdown_count , 0 ) ;
slowdown_count = 0 ;
}
}
2010-05-15 18:48:10 +00:00
xorriso - > pacifier_count + = data_count ;
xorriso - > pacifier_byte_count + = data_count ;
Xorriso_pacifier_callback ( xorriso , " content bytes read " ,
2012-01-23 10:40:59 +00:00
xorriso - > pacifier_count , 0 , " " , 8 ) ;
2010-05-15 18:48:10 +00:00
}
iso_md5_end ( & ctx , data_md5 ) ;
ret = 1 ;
if ( ! iso_md5_match ( md5 , data_md5 ) )
ret = 0 ;
ex : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ctx ! = NULL )
iso_md5_end ( & ctx , data_md5 ) ;
2011-05-08 17:47:43 +00:00
Xorriso_free_meM ( data ) ;
2010-05-15 18:48:10 +00:00
return ( ret ) ;
}
int Xorriso_check_session_md5 ( struct XorrisO * xorriso , char * severity ,
int flag )
{
int ret , i ;
IsoImage * image ;
uint32_t start_lba , end_lba ;
char md5 [ 16 ] , md5_text [ 33 ] ;
ret = Xorriso_get_volume ( xorriso , & image , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
ret = iso_image_get_session_md5 ( image , & start_lba , & end_lba , md5 , 0 ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < 0 )
return ( ret ) ;
if ( ret = = 0 ) {
sprintf ( xorriso - > info_text ,
" No session MD5 is recorded with the loaded session " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
return ( 0 ) ;
}
sprintf ( xorriso - > info_text , " Checking loaded session by its recorded MD5. \n " ) ;
Xorriso_info ( xorriso , 0 ) ;
for ( i = 0 ; i < 16 ; i + + )
sprintf ( md5_text + 2 * i , " %2.2x " , ( ( unsigned char * ) md5 ) [ i ] ) ;
sprintf ( xorriso - > result_line ,
" Session MD5 %s , LBA %.f , %.f blocks \n " ,
md5_text , ( double ) start_lba , ( double ) end_lba - start_lba ) ;
Xorriso_result ( xorriso , 0 ) ;
ret = Xorriso_check_md5_range ( xorriso , ( off_t ) start_lba , ( off_t ) end_lba ,
md5 , 0 ) ;
return ( ret ) ;
}
2010-11-03 08:11:45 +00:00
2010-05-15 18:48:10 +00:00
2010-11-03 08:11:45 +00:00
int Xorriso_check_for_abort ( struct XorrisO * xorriso ,
char * abort_file_path ,
double post_read_time ,
double * last_abort_file_time , int flag )
{
struct stat stbuf ;
if ( abort_file_path [ 0 ] = = 0 )
return ( 0 ) ;
if ( post_read_time - * last_abort_file_time > = 0.1 ) {
if ( stat ( abort_file_path , & stbuf ) ! = - 1 ) {
if ( stbuf . st_mtime > = xorriso - > start_time ) {
sprintf ( xorriso - > info_text ,
" -check_media: Found fresh abort_file=%s " , abort_file_path ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
return ( 1 ) ;
}
}
* last_abort_file_time = post_read_time ;
}
return ( 0 ) ;
}
2010-05-15 18:48:10 +00:00
2012-05-01 07:49:46 +00:00
struct xorriso_md5_state {
/* Resources */
struct XorrisO * xorriso ;
void * ctx ;
struct SpotlisT * spotlist ;
pthread_mutex_t spot_mutex ;
/* Checksum tag cursor */
2024-03-28 14:51:52 +00:00
off_t md5_start ;
off_t next_tag ;
2012-05-01 07:49:46 +00:00
int chain_broken ;
int in_track_gap ;
int was_sb_tag ;
int md5_spot_value ;
2024-03-28 14:51:52 +00:00
off_t md5_spot_lba ;
2012-05-01 07:49:46 +00:00
/* Asynchronous operation */
int slave_state ; /* Operated by slave
0 = not yet started
1 = slave is started
2 = slave has reached its end
3 = slave failed to start
*/
int chunk_size ;
int num_chunks ;
char * * chunk ;
int * chunk_state ; /* 0= content invalid (set by boss at creation time),
1 = content readable ( set by boss ) ,
2 = content was read ( set by MD5 slave ) ,
3 = end - of - processing ( set by boss when done )
*/
int * chunk_fill ; /* Actual number of valid bytes in chunk */
2024-03-28 14:51:52 +00:00
off_t * chunk_lba ;
2012-05-01 07:49:46 +00:00
int chunk_w_idx ; /* Write index. Operated by boss */
int chunk_r_idx ; /* Read index. Operated by MD5 slave */
off_t w_sleeps ;
off_t r_sleeps ;
} ;
int Xorriso__add_spot ( struct xorriso_md5_state * state ,
2024-03-18 17:38:53 +00:00
off_t start_lba , off_t blocks , int quality , int flag )
2012-05-01 07:49:46 +00:00
{
2015-11-13 20:22:51 +00:00
int ret , uret ;
2012-05-01 07:49:46 +00:00
if ( state - > chunk ! = NULL ) {
ret = pthread_mutex_lock ( & ( state - > spot_mutex ) ) ;
if ( ret ! = 0 )
return ( 0 ) ;
}
2024-03-18 17:38:53 +00:00
ret = Spotlist_add_item ( state - > spotlist , start_lba , blocks , quality , 0 ) ;
2015-11-13 20:22:51 +00:00
if ( state - > chunk ! = NULL ) {
uret = pthread_mutex_unlock ( & ( state - > spot_mutex ) ) ;
if ( uret ! = 0 & & ret > 0 )
ret = 0 ;
}
2012-05-01 07:49:46 +00:00
return ( ret ) ;
}
int Xorriso_chunk_md5 ( struct XorrisO * xorriso , char * data , int to_read ,
2024-03-28 14:51:52 +00:00
off_t from_lba , struct xorriso_md5_state * state , int flag )
2012-05-01 07:49:46 +00:00
{
2023-02-28 15:08:41 +00:00
int j , k , ret = 0 , valid , tag_type , decode_ret = 0 ;
2024-03-28 14:51:52 +00:00
uint32_t pos , range_start , range_size , next_tag_uint32 ;
off_t lba ;
2012-05-01 07:49:46 +00:00
char md5 [ 16 ] , tag_md5 [ 16 ] , * tag_type_name = " " , * comparison , * sev_text ;
2023-02-28 15:08:41 +00:00
char md5_text [ 33 ] ;
2012-05-01 07:49:46 +00:00
void * cloned_ctx = NULL ;
for ( j = 0 ; j < to_read ; j + + ) {
lba = j + from_lba ;
2024-03-28 14:51:52 +00:00
if ( lba > ( off_t ) 0xffffffff ) {
if ( lba = = ( off_t ) 0x100000000 ) {
printf ( xorriso - > info_text ,
" Checkreading exceeds the 32-bit block address limit of libisofs MD5 tags " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
}
break ;
}
2012-05-01 07:49:46 +00:00
if ( lba < state - > md5_start )
continue ;
2015-11-08 20:06:10 +00:00
ret = decode_ret = 0 ;
2012-05-01 07:49:46 +00:00
if ( lba > state - > md5_start + 16 & &
( state - > next_tag = = 0 | | state - > chain_broken | | lba = = state - > next_tag ) ) {
ret = iso_util_decode_md5_tag ( data + j * 2048 , & tag_type ,
& pos , & range_start , & range_size ,
2024-03-28 14:51:52 +00:00
& next_tag_uint32 , tag_md5 ,
2012-05-01 07:49:46 +00:00
! ! state - > chain_broken ) ;
2024-03-28 14:51:52 +00:00
if ( ret > 0 & & tag_type > = 2 & & tag_type < = 4 )
state - > next_tag = next_tag_uint32 ;
2015-11-08 20:06:10 +00:00
decode_ret = ret ;
2012-05-01 07:49:46 +00:00
}
valid = ( ret = = 1 | | ret = = ( int ) ISO_MD5_AREA_CORRUPTED ) & & pos = = lba ;
if ( valid & & tag_type = = 2 & & ( lba < state - > md5_start + 32 | |
state - > in_track_gap ) ) {
tag_type_name = " superblock " ;
state - > was_sb_tag = 1 ;
if ( state - > in_track_gap & & range_start ! = state - > md5_start & &
range_start < lba & & lba - range_start < = ( uint32_t ) j ) {
/* Looking for next session : start computing in hindsight.
Session start and superblock tag are supposed to be in the
same 64 kB chunk .
*/
iso_md5_end ( & ( state - > ctx ) , md5 ) ;
ret = iso_md5_start ( & ( state - > ctx ) ) ;
if ( ret < 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
iso_md5_compute ( & ( state - > ctx ) , data + ( j - ( lba - range_start ) ) * 2048 ,
2024-03-28 14:51:52 +00:00
( int ) ( lba - range_start ) * 2048 ) ;
2012-05-01 07:49:46 +00:00
state - > md5_start = range_start ;
state - > in_track_gap = 0 ;
}
} else if ( valid & & tag_type = = 4 & & lba < 32 ) {
tag_type_name = " relocated 64kB superblock " ;
2023-02-28 15:08:41 +00:00
} else if ( valid & & tag_type = = 3 & & state - > was_sb_tag ) {
2012-05-01 07:49:46 +00:00
tag_type_name = " tree " ;
2023-02-28 15:08:41 +00:00
} else if ( valid & & tag_type = = 1 ) {
/* Allow this without superblock and tree tag */
2012-05-01 07:49:46 +00:00
tag_type_name = " session " ;
} else {
tag_type_name = " " ;
}
if ( tag_type_name [ 0 ] ) {
if ( range_start ! = state - > md5_start ) {
sprintf ( xorriso - > info_text ,
" Found MD5 %s tag which covers different data range " , tag_type_name ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
2024-03-28 14:51:52 +00:00
sprintf ( xorriso - > info_text , " Expected start: %.f Found: %lu " ,
( double ) state - > md5_start , ( unsigned long int ) range_start ) ;
2012-05-01 07:49:46 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
2023-02-28 15:08:41 +00:00
for ( k = 0 ; k < 16 ; k + + )
sprintf ( md5_text + 2 * k , " %2.2x " , ( ( unsigned char * ) tag_md5 ) [ k ] ) ;
2024-03-28 14:51:52 +00:00
sprintf ( xorriso - > info_text , " Size: %lu MD5: %s " ,
( unsigned long int ) range_size , md5_text ) ;
2023-02-28 15:08:41 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
2012-05-01 07:49:46 +00:00
state - > chain_broken = 1 ;
valid = 0 ;
} else {
ret = iso_md5_clone ( state - > ctx , & cloned_ctx ) ;
if ( ret < = 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
iso_md5_end ( & cloned_ctx , md5 ) ;
2015-11-08 20:06:10 +00:00
if ( decode_ret = = ( int ) ISO_MD5_AREA_CORRUPTED ) {
2012-05-01 07:49:46 +00:00
comparison = " CORRUPTED " ;
sev_text = " WARNING " ;
state - > md5_spot_value = Xorriso_read_quality_md5_mismatcH ;
state - > chain_broken = 1 ;
} else if ( ! iso_md5_match ( tag_md5 , md5 ) ) {
comparison = " NON-MATCHING " ;
sev_text = " WARNING " ;
state - > md5_spot_value = Xorriso_read_quality_md5_mismatcH ;
state - > chain_broken = 1 ;
} else {
comparison = " matching " ;
sev_text = " UPDATE " ;
state - > md5_spot_value = Xorriso_read_quality_md5_matcH ;
}
state - > md5_spot_lba = lba ;
sprintf ( xorriso - > info_text ,
2024-03-28 14:51:52 +00:00
" Found %s MD5 %s tag: start=%.f size=%.f " ,
comparison , tag_type_name , ( double ) state - > md5_start ,
( double ) ( lba - state - > md5_start ) ) ;
2012-05-01 07:49:46 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , sev_text , 0 ) ;
}
if ( valid & & ( tag_type = = 1 | | ( tag_type = = 4 & & pos = = lba & & lba < 32 ) ) ) {
2018-11-01 10:04:13 +00:00
if ( state - > md5_spot_value ! = Xorriso_read_quality_untesteD ) {
2024-03-28 14:51:52 +00:00
ret = Xorriso__add_spot ( state , state - > md5_start ,
state - > md5_spot_lba - state - > md5_start ,
state - > md5_spot_value , 0 ) ;
2012-05-01 07:49:46 +00:00
if ( ret < = 0 )
goto ex ;
}
state - > md5_spot_value = Xorriso_read_quality_untesteD ;
2023-02-28 15:08:41 +00:00
state - > md5_start = lba + 1 ;
2012-05-01 07:49:46 +00:00
if ( state - > md5_start % 32 )
state - > md5_start = state - > md5_start + ( 32 - ( state - > md5_start % 32 ) ) ;
state - > next_tag = 0 ;
iso_md5_end ( & ( state - > ctx ) , md5 ) ;
ret = iso_md5_start ( & ( state - > ctx ) ) ;
if ( ret < 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
if ( tag_type = = 1 )
state - > in_track_gap = 1 ;
continue ;
}
}
iso_md5_compute ( state - > ctx , data + j * 2048 , 2048 ) ;
}
ret = 1 ;
ex : ;
return ( ret ) ;
}
static void * Xorriso__md5_slave ( void * state_pt )
{
struct xorriso_md5_state * state ;
int ret , c_state , c_idx ;
static int u_wait = 1 ;
state = state_pt ;
state - > slave_state = 1 ;
while ( 1 ) {
c_idx = state - > chunk_r_idx ;
c_state = state - > chunk_state [ c_idx ] ;
if ( c_state = = 1 ) {
ret = Xorriso_chunk_md5 ( state - > xorriso , state - > chunk [ c_idx ] ,
state - > chunk_fill [ c_idx ] , state - > chunk_lba [ c_idx ] ,
state , 0 ) ;
if ( ret < = 0 )
goto ex ;
state - > chunk_state [ c_idx ] = 2 ;
state - > chunk_r_idx = ( c_idx + 1 ) % state - > num_chunks ;
} else if ( c_state = = 3 ) {
goto ex ;
} else {
/* >>> have a timeout ? */ ;
if ( u_wait > 0 )
usleep ( u_wait ) ;
state - > r_sleeps + + ;
}
}
ex : ;
state - > slave_state = 2 ;
return NULL ;
}
int Xorriso_start_chunk_md5 ( struct XorrisO * xorriso ,
struct xorriso_md5_state * state , int flag )
{
int ret , u_wait = 1000 ;
pthread_attr_t attr ;
pthread_attr_t * attr_pt = NULL ;
pthread_t thread ;
pthread_attr_init ( & attr ) ;
pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_DETACHED ) ;
attr_pt = & attr ;
ret = pthread_create ( & thread , attr_pt , Xorriso__md5_slave , state ) ;
if ( ret ! = 0 ) {
sprintf ( xorriso - > info_text ,
" -check_media: Cannot create thread for MD5 computation " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , errno , " FAILURE " , 0 ) ;
ret = 0 ; goto ex ;
}
while ( state - > slave_state ! = 1 ) {
/* >>> have a timeout ? */ ;
/* >>> if this fails set state->slave_state= 3 */
usleep ( u_wait ) ;
}
ret = 1 ;
ex : ;
return ( ret ) ;
}
int Xorriso__wait_chunk_md5 ( struct xorriso_md5_state * state ,
int u_wait , int flag )
{
2015-11-10 09:09:24 +00:00
if ( state - > chunk_state = = NULL )
return ( 1 ) ;
2012-05-01 07:49:46 +00:00
while ( state - > chunk_state [ state - > chunk_w_idx ] = = 1 ) {
/* >>> have a timeout ? */ ;
usleep ( u_wait ) ;
state - > w_sleeps + + ;
}
return ( 1 ) ;
}
int Xorriso__wait_slave_md5_end ( struct xorriso_md5_state * state ,
int u_wait , int flag )
{
while ( state - > slave_state = = 1 ) {
/* >>> have a timeout ? */ ;
usleep ( u_wait ) ;
}
return ( 1 ) ;
}
int Xorriso__end_slave_md5 ( struct xorriso_md5_state * state ,
int u_wait , int flag )
{
int i , ret ;
/* Tell slave thread to end */
for ( i = 0 ; i < state - > num_chunks ; i + + ) {
ret = Xorriso__wait_chunk_md5 ( state , 10000 , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
state - > chunk_state [ state - > chunk_w_idx ] = 3 ;
state - > chunk_w_idx = ( state - > chunk_w_idx + 1 ) % state - > num_chunks ;
}
/* Wait for slave to end */
ret = Xorriso__wait_slave_md5_end ( state , 10000 , 0 ) ;
if ( ret < = 0 )
return ( ret ) ;
return ( 1 ) ;
}
2010-05-15 18:48:10 +00:00
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1 = no pacifier messages
bit2 = compute stream MD5 and look out for checksum tag
@ return < = 0 error , 1 = done , 2 = aborted due to limit
*/
int Xorriso_check_interval ( struct XorrisO * xorriso , struct SpotlisT * spotlist ,
struct CheckmediajoB * job ,
2024-03-18 17:38:53 +00:00
off_t from_lba , off_t block_count , off_t read_chunk ,
off_t md5_start , int flag )
2010-05-15 18:48:10 +00:00
{
2024-03-18 17:38:53 +00:00
int ret , skip_reading , first_value , fret , suspect_tao_end = 0 ;
off_t i , j , total_count = 0 , start_sec , end_sec , start_lba = 0 ;
2024-03-17 15:26:38 +00:00
off_t sectors = - 1 , sector_size = - 1 ;
2010-05-15 18:48:10 +00:00
int prev_quality = - 1 , quality = - 1 , retry = 0 , profile_no , is_cd = 0 ;
2020-12-05 08:53:59 +00:00
int eccb_size = 16 , us_corr = 0 , data_skip ;
2010-05-15 18:48:10 +00:00
char profile_name [ 80 ] ;
struct burn_drive * drive ;
struct burn_drive_info * dinfo ;
2012-05-01 07:49:46 +00:00
char * data = NULL , * data_pt ;
2016-08-25 20:51:30 +00:00
off_t data_count , to_read , read_count = 0 , write_amount , skipped_to_read ;
2020-12-05 08:53:59 +00:00
off_t slowdown_count = 0 , seek_adr ;
2020-08-26 14:29:40 +00:00
struct timeval prev_time ;
2010-05-15 18:48:10 +00:00
double pre_read_time , post_read_time , time_diff , total_time_diff = 0 ;
double last_abort_file_time = 0 ;
2012-05-01 07:49:46 +00:00
void * ctx = NULL ;
char md5 [ 16 ] ;
size_t data_size ;
struct xorriso_md5_state state ;
int num_chunks , async_md5 ;
static off_t chunks_limit = 256 * 1024 * 1024 ;
memset ( & state , 0 , sizeof ( state ) ) ;
state . chunk = NULL ;
state . chunk_state = NULL ;
state . chunk_fill = NULL ;
state . chunk_lba = NULL ;
state . spotlist = spotlist ;
2010-05-15 18:48:10 +00:00
2012-02-01 16:31:48 +00:00
if ( read_chunk > 1024 )
read_chunk = 1024 ;
else if ( read_chunk < 1 )
read_chunk = 1 ;
2020-12-05 08:53:59 +00:00
data_skip = job - > data_to_skip ;
2012-05-01 07:49:46 +00:00
num_chunks = job - > async_chunks ;
if ( ( ( off_t ) num_chunks ) * ( ( off_t ) read_chunk ) > chunks_limit )
num_chunks = chunks_limit / read_chunk ;
async_md5 = ( num_chunks > = 2 ) ;
if ( async_md5 )
data_size = num_chunks * read_chunk * 2048 ;
else
data_size = read_chunk * 2048 ;
Xorriso_alloc_meM ( data , char , data_size ) ;
data_pt = data ;
2011-05-02 21:12:45 +00:00
2010-05-15 18:48:10 +00:00
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to check media readability " ,
2 * ! ! job - > use_dev ) ;
if ( ret < = 0 )
goto ex ;
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
2012-02-01 12:26:59 +00:00
if ( ret > 0 ) {
2014-04-19 11:52:07 +00:00
if ( profile_no > = 0x08 & & profile_no < = 0x0a ) {
2010-05-15 18:48:10 +00:00
is_cd = 1 ;
2014-04-19 11:52:07 +00:00
eccb_size = 1 ;
} else if ( profile_no > = 0x40 & & profile_no < = 0x43 ) {
eccb_size = 32 ;
} else if ( burn_drive_get_drive_role ( drive ) ! = 1 ) {
eccb_size = 1 ;
}
2012-02-01 12:26:59 +00:00
}
2010-05-15 18:48:10 +00:00
if ( job - > sector_map ! = NULL ) {
Sectorbitmap_get_layout ( job - > sector_map , & sectors , & sector_size , 0 ) ;
sector_size / = 2048 ;
}
if ( job - > retry > 0 )
retry = 1 ;
else if ( job - > retry = = 0 & & is_cd )
retry = 1 ;
if ( flag & 4 ) {
ret = iso_md5_start ( & ctx ) ;
if ( ret < 0 ) {
Xorriso_no_malloc_memory ( xorriso , NULL , 0 ) ;
ret = - 1 ; goto ex ;
}
}
2012-05-01 07:49:46 +00:00
state . xorriso = xorriso ;
state . ctx = ctx ;
state . spotlist = spotlist ;
state . md5_start = md5_start ;
state . next_tag = 0 ;
state . chain_broken = 0 ;
state . in_track_gap = 0 ;
state . was_sb_tag = 0 ;
state . md5_spot_value = Xorriso_read_quality_untesteD ;
state . md5_spot_lba = 0 ;
state . slave_state = 0 ;
state . chunk_size = read_chunk ;
if ( async_md5 ) {
state . num_chunks = num_chunks ;
Xorriso_alloc_meM ( state . chunk , char * , num_chunks ) ;
Xorriso_alloc_meM ( state . chunk_state , int , num_chunks ) ;
Xorriso_alloc_meM ( state . chunk_fill , int , num_chunks ) ;
2024-03-28 14:51:52 +00:00
Xorriso_alloc_meM ( state . chunk_lba , off_t , num_chunks ) ;
2012-05-01 07:49:46 +00:00
for ( i = 0 ; i < state . num_chunks ; i + + ) {
state . chunk [ i ] = data + read_chunk * i * 2048 ;
state . chunk_state [ i ] = 0 ;
state . chunk_fill [ i ] = 0 ;
state . chunk_lba [ i ] = 0 ;
}
ret = pthread_mutex_init ( & ( state . spot_mutex ) , NULL ) ;
if ( ret ! = 0 ) {
sprintf ( xorriso - > info_text ,
" -check_media: Cannot initialize thread mutex " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , errno , " FAILURE " , 0 ) ;
goto ex ;
}
} else
state . num_chunks = 0 ;
state . chunk_w_idx = 0 ;
state . chunk_r_idx = 0 ;
state . w_sleeps = 0 ;
state . r_sleeps = 0 ;
if ( async_md5 ) {
ret = Xorriso_start_chunk_md5 ( xorriso , & state , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
2020-08-26 14:29:40 +00:00
if ( xorriso - > read_speed_force > 0 ) /* initialize forced speed limit */
burn_nominal_slowdown ( xorriso - > read_speed_force , xorriso - > read_speed_corr ,
& prev_time , & us_corr , ( off_t ) 0 , 1 ) ;
Xorriso_set_speed ( xorriso , drive , xorriso - > read_speed , 0 , 1 ) ;
2013-10-08 17:58:09 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2010-05-15 18:48:10 +00:00
start_lba = from_lba ;
to_read = read_chunk ;
post_read_time = Sfile_microtime ( 0 ) ;
for ( i = 0 ; i < block_count ; i + = to_read ) {
2020-12-05 08:53:59 +00:00
if ( i ! = 0 )
data_skip = 0 ;
2010-05-15 18:48:10 +00:00
skip_reading = 0 ;
2010-11-03 08:11:45 +00:00
ret = Xorriso_check_for_abort ( xorriso , job - > abort_file_path , post_read_time ,
& last_abort_file_time , 0 ) ;
if ( ret = = 1 )
goto abort_check ;
2010-05-15 18:48:10 +00:00
if ( job - > item_limit > 0 & &
Spotlist_count ( spotlist , 0 ) + 2 > = job - > item_limit ) {
sprintf ( xorriso - > info_text , " -check_media: Reached item_limit=%d " ,
job - > item_limit ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
goto abort_check ;
}
pre_read_time = Sfile_microtime ( 0 ) ;
if ( job - > time_limit > 0
& & job - > start_time + job - > time_limit < pre_read_time ) {
sprintf ( xorriso - > info_text , " -check_media: Reached time_limit=%d " ,
job - > time_limit ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
abort_check : ;
if ( prev_quality > = 0 ) {
2012-05-01 07:49:46 +00:00
ret = Xorriso__add_spot ( & state , start_lba , i + from_lba - start_lba ,
2010-05-15 18:48:10 +00:00
prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
2012-05-01 07:49:46 +00:00
ret = Xorriso__add_spot ( & state , i + from_lba , block_count - i ,
2010-05-15 18:48:10 +00:00
Xorriso_read_quality_untesteD , 0 ) ;
if ( ret > 0 )
ret = 2 ;
goto ex ;
}
to_read = read_chunk ;
2016-08-25 20:51:30 +00:00
skipped_to_read = 0 ;
2012-10-25 12:57:08 +00:00
suspect_tao_end = 0 ;
2010-05-15 18:48:10 +00:00
if ( i + to_read > block_count )
to_read = block_count - i ;
if ( is_cd & & i + to_read + 2 > = block_count ) {
/* Read last 2 blocks of CD track separately, because with TAO tracks
they are always unreadable but with SAO tracks they contain data .
*/
2016-03-08 07:54:53 +00:00
if ( to_read > 2 ) {
2010-05-15 18:48:10 +00:00
to_read - = 2 ;
2016-03-08 07:54:53 +00:00
} else {
if ( to_read > 1 )
2010-05-15 18:48:10 +00:00
to_read - - ;
2012-10-25 12:57:08 +00:00
suspect_tao_end = 1 ;
2010-05-15 18:48:10 +00:00
}
}
if ( sector_size = = read_chunk & & from_lba % read_chunk = = 0
& & ! skip_reading ) {
2024-03-18 17:38:53 +00:00
if ( Sectorbitmap_is_set ( job - > sector_map , ( i + from_lba ) / sector_size , 0 ) ) {
2010-05-15 18:48:10 +00:00
quality = Xorriso_read_quality_valiD ;
skip_reading = 1 ;
}
} else if ( sector_size > 0 & & ! skip_reading ) {
start_sec = ( i + from_lba ) / sector_size ;
end_sec = ( i + to_read + from_lba ) / sector_size ;
2024-03-18 17:38:53 +00:00
first_value = Sectorbitmap_is_set ( job - > sector_map , start_sec , 0 ) ;
2010-05-15 18:48:10 +00:00
for ( j = start_sec ; j < end_sec ; j + + )
2024-03-18 17:38:53 +00:00
if ( Sectorbitmap_is_set ( job - > sector_map , j , 0 ) ! = first_value )
2010-05-15 18:48:10 +00:00
break ;
to_read = j * sector_size - i - from_lba ;
skip_reading = ! ! first_value ;
if ( skip_reading )
quality = Xorriso_read_quality_valiD ;
}
if ( skip_reading ) {
pre_read_time = post_read_time = Sfile_microtime ( 0 ) ;
2016-08-25 20:51:30 +00:00
skipped_to_read = to_read ;
2010-05-15 18:48:10 +00:00
} else {
data_count = 0 ;
pre_read_time = Sfile_microtime ( 0 ) ;
2012-05-01 07:49:46 +00:00
if ( async_md5 ) {
ret = Xorriso__wait_chunk_md5 ( & state , 1 , 0 ) ;
if ( ret < = 0 )
goto ex ;
data_pt = state . chunk [ state . chunk_w_idx ] ;
}
2024-03-18 17:38:53 +00:00
ret = burn_read_data ( drive , ( i + from_lba ) * ( off_t ) 2048 ,
2012-10-25 12:57:08 +00:00
data_pt , to_read * ( off_t ) 2048 , & data_count ,
( 4 * ! retry ) | ( 16 * ! ! suspect_tao_end ) ) ;
2010-05-15 18:48:10 +00:00
post_read_time = Sfile_microtime ( 0 ) ;
time_diff = post_read_time - pre_read_time ;
total_time_diff + = time_diff ;
total_count + + ;
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( data_count / 2048 < to_read ) {
if ( data_count > 0 & & retry ) {
if ( prev_quality > = 0 ) {
2012-05-01 07:49:46 +00:00
ret = Xorriso__add_spot ( & state , start_lba ,
2010-05-15 18:48:10 +00:00
i + from_lba - start_lba , prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
2024-03-18 17:38:53 +00:00
ret = Xorriso__add_spot ( & state , i + from_lba ,
data_count / ( off_t ) 2048 ,
2010-05-15 18:48:10 +00:00
Xorriso_read_quality_partiaL , 0 ) ;
if ( ret < = 0 )
goto ex ;
start_lba = i + from_lba + data_count / 2048 ;
2012-10-25 12:57:08 +00:00
if ( suspect_tao_end & & ret = = - 3 )
prev_quality = Xorriso_read_quality_tao_enD ;
else
prev_quality = Xorriso_read_quality_unreadablE ;
2010-05-15 18:48:10 +00:00
}
2012-10-25 12:57:08 +00:00
if ( suspect_tao_end & & ret = = - 3 )
quality = Xorriso_read_quality_tao_enD ;
else
quality = Xorriso_read_quality_unreadablE ;
2014-04-19 11:52:07 +00:00
if ( retry ) /* skip one eccb_size */
to_read = data_count / 2048 + eccb_size ;
} else { /* (can hardly happen) */
2010-05-15 18:48:10 +00:00
quality = Xorriso_read_quality_partiaL ;
2014-04-19 11:52:07 +00:00
}
2010-05-15 18:48:10 +00:00
fret = Xorriso_eval_problem_status ( xorriso , ret , 1 | 2 ) ;
if ( fret < 0 )
goto ex ;
} else {
quality = Xorriso_read_quality_gooD ;
if ( time_diff > job - > slow_threshold_seq & & job - > slow_threshold_seq > 0 & &
i > 0 )
quality = Xorriso_read_quality_sloW ;
}
/* MD5 checksumming */
if ( ctx ! = NULL ) {
2012-05-01 07:49:46 +00:00
if ( async_md5 ) {
state . chunk_fill [ state . chunk_w_idx ] = to_read ;
state . chunk_lba [ state . chunk_w_idx ] = i + from_lba ;
state . chunk_state [ state . chunk_w_idx ] = 1 ;
/* The MD5 thread will call Xorriso_chunk_md5() */
2010-05-15 18:48:10 +00:00
2012-05-01 07:49:46 +00:00
state . chunk_w_idx = ( state . chunk_w_idx + 1 ) % state . num_chunks ;
} else {
ret = Xorriso_chunk_md5 ( xorriso , data_pt , to_read ,
2024-03-28 14:51:52 +00:00
i + from_lba , & state , 0 ) ;
2012-05-01 07:49:46 +00:00
if ( ret < = 0 )
goto ex ;
2010-05-15 18:48:10 +00:00
}
}
2020-12-05 08:53:59 +00:00
write_amount = data_count - data_skip ;
2010-05-15 18:48:10 +00:00
if ( data_count > 0 ) {
2020-12-05 08:53:59 +00:00
read_count + = data_count - data_skip ;
2010-05-15 18:48:10 +00:00
if ( job - > data_to_limit > = 0 & & read_count > job - > data_to_limit )
write_amount - = ( read_count - job - > data_to_limit ) ;
}
2020-08-26 14:29:40 +00:00
if ( xorriso - > read_speed_force > 0 ) {
slowdown_count + = data_count ;
if ( slowdown_count > = 128 * 1024 ) {
burn_nominal_slowdown ( xorriso - > read_speed_force ,
xorriso - > read_speed_corr ,
& prev_time , & us_corr , slowdown_count , 0 ) ;
slowdown_count = 0 ;
}
}
2010-05-15 18:48:10 +00:00
if ( write_amount > 0 ) {
if ( job - > data_to_fd > = 0 ) {
2024-03-18 17:38:53 +00:00
seek_adr = ( i + from_lba ) * ( off_t ) 2048 +
2020-12-05 08:53:59 +00:00
job - > data_to_skip + job - > data_to_offset ;
if ( strcmp ( job - > data_to_path , " - " ) ! = 0 ) {
ret = lseek ( job - > data_to_fd , seek_adr , SEEK_SET ) ;
if ( ret = = - 1 ) {
2010-05-15 18:48:10 +00:00
failed_to_write : ;
2020-12-05 08:53:59 +00:00
sprintf ( xorriso - > info_text ,
" Cannot write %d bytes to position %.f in " ,
( int ) data_count , ( double ) seek_adr ) ;
Text_shellsafe ( job - > data_to_path , xorriso - > info_text , 1 ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , errno ,
" FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
2010-05-15 18:48:10 +00:00
}
2020-12-05 08:53:59 +00:00
ret = write ( job - > data_to_fd , data_pt + data_skip , write_amount ) ;
2010-05-15 18:48:10 +00:00
if ( ret = = - 1 )
goto failed_to_write ;
}
}
}
if ( quality ! = prev_quality ) {
if ( prev_quality > = 0 ) {
2012-05-01 07:49:46 +00:00
ret = Xorriso__add_spot ( & state , start_lba ,
i + from_lba - start_lba , prev_quality , 0 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 )
goto ex ;
}
start_lba = i + from_lba ;
prev_quality = quality ;
}
if ( ! ( flag & 2 ) ) {
2016-08-25 20:51:30 +00:00
xorriso - > pacifier_count + = to_read - skipped_to_read ;
2010-05-15 18:48:10 +00:00
if ( post_read_time - xorriso - > last_update_time > =
xorriso - > pacifier_interval )
2012-01-23 10:38:48 +00:00
Xorriso_pacifier_callback ( xorriso , " blocks read " ,
2012-02-01 16:29:26 +00:00
xorriso - > pacifier_count , xorriso - > pacifier_total , " " ,
8 | 16 | ( 128 * ( job - > use_dev = = 1 ) ) ) ;
2010-05-15 18:48:10 +00:00
}
}
if ( prev_quality > = 0 ) {
2012-05-01 07:49:46 +00:00
ret = Xorriso__add_spot ( & state , start_lba ,
2010-05-15 18:48:10 +00:00
block_count + from_lba - start_lba , prev_quality , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
/* <<< for calibration of quality */
if ( total_count > 0 ) {
2024-03-18 17:38:53 +00:00
sprintf ( xorriso - > info_text , " Xorriso_check_interval: %.1f s / %.f = %f " ,
total_time_diff , ( double ) total_count ,
( double ) total_time_diff / total_count ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " DEBUG " , 0 ) ;
}
/* MD5 checksumming : register result */
2012-05-01 07:49:46 +00:00
if ( async_md5 ) {
ret = Xorriso__end_slave_md5 ( & state , 10000 , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
2010-05-15 18:48:10 +00:00
/* >>> ??? allow chain_broken to be a match ? */
2012-05-01 07:49:46 +00:00
if ( state . next_tag > 0 ) {
2024-03-28 14:51:52 +00:00
sprintf ( xorriso - > info_text , " Missing announced MD5 tag: start=%.f pos=%.f " ,
( double ) state . md5_start , ( double ) state . next_tag ) ;
2010-05-15 18:48:10 +00:00
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " WARNING " , 0 ) ;
2012-05-01 07:49:46 +00:00
state . md5_spot_value = Xorriso_read_quality_md5_mismatcH ;
state . md5_spot_lba = state . next_tag ;
2010-05-15 18:48:10 +00:00
}
2012-05-01 07:49:46 +00:00
if ( state . md5_spot_value ! = Xorriso_read_quality_untesteD ) {
2024-03-28 14:51:52 +00:00
ret = Xorriso__add_spot ( & state , state . md5_start ,
state . md5_spot_lba - state . md5_start ,
2024-03-18 17:38:53 +00:00
state . md5_spot_value , 0 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 )
goto ex ;
}
ret = 1 ;
2012-05-01 07:49:46 +00:00
ex : ;
if ( async_md5 ) {
Xorriso__end_slave_md5 ( & state , 10000 , 0 ) ;
sprintf ( xorriso - > info_text ,
2024-03-18 17:38:53 +00:00
" async_chunks=%d , chunk_size=%.fs , w_sleeps: %.f , r_sleeps: %.f " ,
state . num_chunks , ( double ) read_chunk , ( double ) state . w_sleeps ,
2012-05-01 07:49:46 +00:00
( double ) state . r_sleeps ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " DEBUG " , 0 ) ;
if ( state . chunk ! = NULL )
pthread_mutex_destroy ( & ( state . spot_mutex ) ) ;
Xorriso_free_meM ( state . chunk ) ;
Xorriso_free_meM ( state . chunk_state ) ;
Xorriso_free_meM ( state . chunk_fill ) ;
Xorriso_free_meM ( state . chunk_lba ) ;
}
2011-05-02 21:12:45 +00:00
Xorriso_free_meM ( data ) ;
2012-05-01 07:49:46 +00:00
if ( state . ctx ! = NULL )
iso_md5_end ( & ( state . ctx ) , md5 ) ;
2010-05-15 18:48:10 +00:00
return ( ret ) ;
}
int Xorriso_check_media ( struct XorrisO * xorriso , struct SpotlisT * * spotlist ,
struct CheckmediajoB * job , int flag )
{
2024-03-18 17:38:53 +00:00
int ret , mode , os_errno , j ;
int num_sessions , num_tracks , declare_untested = 0 ;
int hret , quality , profile_no ;
2024-03-17 21:07:23 +00:00
off_t i , blocks , last_track_end = - 1 , count , track_lba , start_lba = 0 ;
2024-03-18 17:38:53 +00:00
off_t media_blocks = 0 , read_chunk = 32 , md5_start , track_blocks ;
off_t read_capacity = - 1 , end_lba ;
off_t track_bad_claim = 0 ;
2013-09-05 08:03:59 +00:00
char * toc_info = NULL , profile_name [ 80 ] , msg [ 160 ] ;
2010-05-15 18:48:10 +00:00
struct burn_drive * drive ;
struct burn_drive_info * dinfo ;
2012-02-01 12:26:59 +00:00
enum burn_disc_status s ;
2010-05-15 18:48:10 +00:00
struct isoburn_toc_disc * isoburn_disc = NULL ;
struct isoburn_toc_session * * isoburn_sessions ;
struct isoburn_toc_track * * iso_burn_tracks ;
struct burn_toc_entry isoburn_entry ;
struct stat stbuf ;
struct burn_multi_caps * caps = NULL ;
* spotlist = NULL ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to check media readability " ,
2 * ! ! job - > use_dev ) ;
if ( ret < = 0 )
goto ex ;
2012-05-01 07:49:46 +00:00
ret = burn_disc_get_profile ( drive , & profile_no , profile_name ) ;
if ( ret < = 0 )
profile_no = 0 ;
2012-05-02 11:09:40 +00:00
2010-05-15 18:48:10 +00:00
if ( job - > min_block_size ! = 0 )
read_chunk = job - > min_block_size ;
ret = Spotlist_new ( spotlist , 0 ) ;
if ( ret < = 0 )
{ ret = - 1 ; goto ex ; }
if ( job - > sector_map_path [ 0 ] ) {
Sectorbitmap_destroy ( & ( job - > sector_map ) , 0 ) ;
if ( stat ( job - > sector_map_path , & stbuf ) ! = - 1 ) {
ret = Sectorbitmap_from_file ( & ( job - > sector_map ) , job - > sector_map_path ,
xorriso - > info_text , & os_errno , 0 ) ;
if ( ret < = 0 ) {
if ( xorriso - > info_text [ 0 ] )
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , os_errno ,
" FAILURE " , 0 ) ;
goto ex ;
}
}
2013-02-26 10:33:01 +00:00
Xorriso_toc_to_string ( xorriso , & toc_info ,
( 2 * ! ! job - > use_dev ) | ( 4 * ! job - > map_with_volid ) ) ;
2010-05-15 18:48:10 +00:00
}
ret = Xorriso_open_job_data_to ( xorriso , job , 0 ) ;
if ( ret < = 0 )
goto ex ;
Xorriso_pacifier_reset ( xorriso , 0 ) ;
job - > start_time = time ( NULL ) ;
mode = job - > mode ;
if ( job - > min_lba > 0 ) {
start_lba = job - > min_lba ;
2024-03-18 08:44:24 +00:00
ret = Spotlist_add_item ( * spotlist , ( off_t ) 0 , job - > min_lba ,
2010-05-15 18:48:10 +00:00
Xorriso_read_quality_untesteD , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
2012-02-01 12:26:59 +00:00
s = isoburn_disc_get_status ( drive ) ;
if ( s ! = BURN_DISC_APPENDABLE & & s ! = BURN_DISC_FULL ) {
2023-02-28 15:08:41 +00:00
ret = 0 ;
if ( s = = BURN_DISC_BLANK ) {
/* check whether medium is overwritable */
ret = burn_disc_get_multi_caps ( drive , BURN_WRITE_NONE , & caps , 0 ) ;
if ( ret > 0 )
if ( caps - > start_adr = = 0 )
ret = 0 ;
}
if ( ret < = 0 ) {
no_readable_medium : ;
Xorriso_msgs_submit ( xorriso , 0 , " -check_media: No readable medium found " ,
0 , " SORRY " , 0 ) ;
ret = 0 ; goto ex ;
}
2012-02-01 12:26:59 +00:00
}
2024-03-18 17:38:53 +00:00
ret = burn_get_read_capacity_v2 ( drive , & read_capacity , 0 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 )
read_capacity = - 1 ;
2023-02-28 15:08:41 +00:00
if ( s = = BURN_DISC_BLANK & & read_capacity < = 0 )
goto no_readable_medium ;
2010-05-15 18:48:10 +00:00
if ( job - > max_lba > = 0 ) {
blocks = job - > max_lba + 1 - start_lba ;
xorriso - > pacifier_total = blocks ;
2024-03-17 21:07:23 +00:00
ret = Xorriso_check_interval ( xorriso , * spotlist , job , ( int ) start_lba , ( int ) blocks ,
read_chunk , ( int ) start_lba , 0 ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 )
goto ex ;
} else if ( mode = = 0 ) { /* track by track */
2023-02-28 15:08:41 +00:00
if ( s = = BURN_DISC_BLANK ) {
no_tracks_found : ;
Xorriso_msgs_submit ( xorriso , 0 , " -check_media: No tracks found on medium " ,
0 , " SORRY " , 0 ) ;
ret = 0 ; goto ex ;
}
2010-05-15 18:48:10 +00:00
isoburn_disc = isoburn_toc_drive_get_disc ( drive ) ;
if ( isoburn_disc = = NULL )
2011-07-24 20:39:38 +00:00
goto libburn_whole_disc ;
2010-05-15 18:48:10 +00:00
isoburn_sessions =
isoburn_toc_disc_get_sessions ( isoburn_disc , & num_sessions ) ;
for ( i = 0 ; i < num_sessions ; i + + ) {
iso_burn_tracks = isoburn_toc_session_get_tracks ( isoburn_sessions [ i ] ,
& num_tracks ) ;
for ( j = 0 ; j < num_tracks ; j + + ) {
isoburn_toc_track_get_entry ( iso_burn_tracks [ j ] , & isoburn_entry ) ;
if ( ! ( isoburn_entry . extensions_valid & 1 ) ) /* should not happen */
continue ;
track_lba = isoburn_entry . start_lba ;
track_blocks = isoburn_entry . track_blocks ;
2010-10-21 18:04:07 +00:00
/* The last track of an appendable BD-R reports more blocks than the
read capacity allows . All BD - R track sizes are multiple of 64 kB .
*/
if ( i = = num_sessions - 1 & &
( track_lba + track_blocks > read_capacity & &
track_lba + track_blocks < read_capacity + 32 & &
( profile_no = = 0x41 | | profile_no = = 0x40 ) ) )
track_blocks = read_capacity - track_lba ;
2013-09-05 08:03:59 +00:00
if ( track_lba + track_blocks > read_capacity ) {
if ( track_bad_claim < track_lba + track_blocks )
track_bad_claim = track_lba + track_blocks ;
if ( track_lba > = read_capacity ) {
sprintf ( msg , " -check_media: Track %d of session %d begins after end of readable medium area. " ,
2024-03-17 21:07:23 +00:00
j + 1 , ( int ) ( i + 1 ) ) ;
2013-09-05 08:03:59 +00:00
Xorriso_msgs_submit ( xorriso , 0 , msg , 0 , " WARNING " , 0 ) ;
continue ;
} else {
2016-03-08 07:54:53 +00:00
if ( profile_no > = 0x08 & & profile_no < = 0x0a & &
track_lba + track_blocks = = read_capacity + 2 & &
i = = num_sessions - 1 & & j = = num_tracks - 1 ) {
sprintf ( msg , " -check_media: Last CD track exceeds readable area by 2 blocks. Assuming TAO. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , msg , 0 , " DEBUG " , 0 ) ;
} else {
sprintf ( msg , " -check_media: Track %d of session %d extends over the end of readable medium area. " ,
2024-03-17 21:07:23 +00:00
j + 1 , ( int ) ( i + 1 ) ) ;
2016-03-08 07:54:53 +00:00
Xorriso_msgs_submit ( xorriso , 0 , msg , 0 , " WARNING " , 0 ) ;
}
2013-09-05 08:03:59 +00:00
track_blocks = read_capacity - track_lba ;
}
}
2010-05-15 18:48:10 +00:00
md5_start = track_lba ;
if ( i = = 0 & & j = = 0 ) {
if ( track_lba = = 32 ) {
ret = burn_disc_get_multi_caps ( drive , BURN_WRITE_NONE , & caps , 0 ) ;
if ( ret > 0 ) {
if ( caps - > start_adr ) {
2019-10-28 14:34:56 +00:00
/* block 0 to 31 are the overall mount entry of overwritable */
2010-05-15 18:48:10 +00:00
track_lba = 0 ;
track_blocks + = 32 ;
}
}
}
}
if ( last_track_end > = 0 & & last_track_end < track_lba & &
last_track_end > = start_lba ) {
ret = Spotlist_add_item ( * spotlist , last_track_end ,
track_lba - last_track_end ,
Xorriso_read_quality_off_tracK , 0 ) ;
if ( ret < = 0 )
goto ex ;
}
last_track_end = track_lba + track_blocks ;
if ( track_lba < start_lba ) {
track_blocks - = start_lba - track_lba ;
track_lba = start_lba ;
}
if ( track_blocks < = 0 )
continue ;
if ( declare_untested ) {
2024-03-18 17:38:53 +00:00
ret = Spotlist_add_item ( * spotlist , track_lba , track_blocks ,
2010-05-15 18:48:10 +00:00
Xorriso_read_quality_untesteD , 0 ) ;
if ( ret < = 0 )
goto ex ;
} else {
2024-03-17 21:07:23 +00:00
ret = Xorriso_check_interval ( xorriso , * spotlist , job , ( int ) track_lba ,
2010-05-15 18:48:10 +00:00
track_blocks , read_chunk , md5_start ,
( i > 0 ) | ( 4 * ( xorriso - > do_md5 & 1 ) ) ) ;
if ( ret < = 0 )
goto ex ;
if ( ret = = 2 )
declare_untested = 1 ;
}
}
}
2013-09-05 08:03:59 +00:00
if ( track_bad_claim > read_capacity ) {
2016-03-08 07:54:53 +00:00
count = Spotlist_count ( * spotlist , 0 ) ;
Spotlist_get_item ( * spotlist , count - 1 , & track_lba , & blocks , & quality , 0 ) ;
if ( profile_no > = 0x08 & & profile_no < = 0x0a & &
track_bad_claim - read_capacity = = 2 & &
quality ! = Xorriso_read_quality_tao_enD )
quality = Xorriso_read_quality_tao_enD ;
else
quality = Xorriso_read_quality_unreadablE ;
2024-03-18 17:38:53 +00:00
ret = Spotlist_add_item ( * spotlist , read_capacity ,
( track_bad_claim - read_capacity ) , quality , 0 ) ;
2013-09-05 08:03:59 +00:00
if ( ret < = 0 )
goto ex ;
}
2012-02-14 10:32:43 +00:00
} else if ( mode = = 1 ) { /* Image range */
/* Default is the emulated disc capacity.
*/
2023-02-28 15:08:41 +00:00
if ( s = = BURN_DISC_BLANK )
goto no_tracks_found ;
2010-05-15 18:48:10 +00:00
isoburn_disc = isoburn_toc_drive_get_disc ( drive ) ;
2011-07-24 20:39:38 +00:00
if ( isoburn_disc = = NULL )
goto libburn_whole_disc ;
2024-04-03 16:56:09 +00:00
blocks = media_blocks = isoburn_toc_disc_get_sectors_v2 ( isoburn_disc ) ;
2012-02-14 10:32:43 +00:00
/* If possible, determine the end address of the loaded ISO image.
*/
2024-04-03 16:56:09 +00:00
track_lba = isoburn_get_attached_start_lba_v2 ( drive ) ;
2012-02-14 10:32:43 +00:00
if ( track_lba > = 0 ) {
2024-03-18 17:38:53 +00:00
ret = isoburn_read_iso_head_v2 ( drive , track_lba , & track_blocks , NULL , 0 ) ;
2012-02-14 10:32:43 +00:00
if ( ret > 0 ) {
blocks = media_blocks = track_lba + track_blocks ;
}
}
2010-05-15 18:48:10 +00:00
if ( start_lba > = 0 )
blocks - = start_lba ;
if ( media_blocks < = 0 )
2011-07-24 20:39:38 +00:00
goto libburn_whole_disc ;
2010-05-15 18:48:10 +00:00
xorriso - > pacifier_total = blocks ;
2024-03-17 21:07:23 +00:00
ret = Xorriso_check_interval ( xorriso , * spotlist , job , ( int ) start_lba , ( int ) blocks ,
read_chunk , ( int ) start_lba , ( 4 * ( xorriso - > do_md5 & 1 ) ) ) ;
2010-05-15 18:48:10 +00:00
if ( ret < = 0 )
goto ex ;
} else if ( mode = = 2 ) {
2011-07-24 20:39:38 +00:00
libburn_whole_disc : ;
2011-11-02 14:21:29 +00:00
/* single sweep over libburn medium capacity */
2024-03-17 21:07:23 +00:00
ret = burn_get_read_capacity_v2 ( drive , & blocks , 0 ) ;
2011-07-24 20:39:38 +00:00
if ( ret < = 0 ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
sprintf ( xorriso - > info_text , " No content detected on media " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
{ ret = 0 ; goto ex ; }
}
2012-01-18 09:35:43 +00:00
blocks - = start_lba ;
2011-07-24 20:39:38 +00:00
xorriso - > pacifier_total = blocks ;
2024-03-17 21:07:23 +00:00
ret = Xorriso_check_interval ( xorriso , * spotlist , job , ( int ) start_lba , ( int ) blocks ,
read_chunk , ( int ) start_lba , ( 4 * ( xorriso - > do_md5 & 1 ) ) ) ;
2011-07-24 20:39:38 +00:00
if ( ret < = 0 )
goto ex ;
2010-05-15 18:48:10 +00:00
}
2012-01-23 10:38:48 +00:00
Xorriso_pacifier_callback ( xorriso , " blocks read " ,
xorriso - > pacifier_count , xorriso - > pacifier_total , " " ,
2012-02-01 16:31:48 +00:00
1 | 8 | 16 | 32 | ( 128 * ( job - > use_dev = = 1 ) ) ) ;
2010-05-15 18:48:10 +00:00
ret = 1 ;
ex : ;
2020-09-30 19:07:50 +00:00
if ( job - > data_to_fd ! = - 1 & & strcmp ( job - > data_to_path , " - " ) ! = 0 )
2010-05-15 18:48:10 +00:00
close ( job - > data_to_fd ) ;
job - > data_to_fd = - 1 ;
if ( read_capacity > = 0 ) {
count = Spotlist_count ( * spotlist , 0 ) ;
end_lba = 0 ;
for ( i = 0 ; i < count ; i + + ) {
Spotlist_get_item ( * spotlist , i , & start_lba , & blocks , & quality , 0 ) ;
if ( start_lba + blocks > end_lba )
end_lba = start_lba + blocks ;
}
if ( read_capacity > end_lba ) {
2024-03-18 17:38:53 +00:00
hret = Spotlist_add_item ( * spotlist , end_lba , ( read_capacity - end_lba ) ,
2010-05-15 18:48:10 +00:00
Xorriso_read_quality_untesteD , 0 ) ;
if ( hret < ret )
ret = hret ;
}
}
if ( ret > 0 )
2024-03-18 17:38:53 +00:00
ret = Xorriso_update_in_sector_map ( xorriso , * spotlist , read_chunk ,
2024-03-17 21:07:23 +00:00
job , 0 ) ;
2010-05-15 18:48:10 +00:00
if ( ret > 0 ) {
2024-03-18 17:38:53 +00:00
ret = Xorriso_spotlist_to_sectormap ( xorriso , * spotlist , read_chunk ,
2014-01-23 20:08:06 +00:00
& ( job - > sector_map ) , 2 ) ;
2010-05-15 18:48:10 +00:00
if ( ret > 0 & & job - > sector_map_path [ 0 ] ) {
ret = Sectorbitmap_to_file ( job - > sector_map , job - > sector_map_path , toc_info ,
xorriso - > info_text , & os_errno , 0 ) ;
if ( ret < = 0 ) {
if ( xorriso - > info_text [ 0 ] )
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , os_errno ,
" FAILURE " , 0 ) ;
}
}
}
if ( toc_info ! = NULL )
free ( toc_info ) ;
if ( ret < = 0 )
Spotlist_destroy ( spotlist , 0 ) ;
if ( caps ! = NULL )
burn_disc_free_multi_caps ( & caps ) ;
2011-05-03 06:29:50 +00:00
if ( isoburn_disc ! = NULL )
isoburn_toc_disc_free ( isoburn_disc ) ;
2010-05-15 18:48:10 +00:00
return ( ret ) ;
}
/* @param flag
bit0 = if not MMC drive print NOTE and return 2
bit1 = obtain outdrive , else indrive
bit4 = do not report failure
*/
int Xorriso_get_drive_handles ( struct XorrisO * xorriso ,
struct burn_drive_info * * dinfo ,
struct burn_drive * * drive ,
char * attempt , int flag )
{
int ret ;
if ( flag & 2 )
* dinfo = ( struct burn_drive_info * ) xorriso - > out_drive_handle ;
else
* dinfo = ( struct burn_drive_info * ) xorriso - > in_drive_handle ;
if ( * dinfo = = NULL & & ! ( flag & 16 ) ) {
Xorriso_process_msg_queues ( xorriso , 0 ) ;
2015-09-20 12:51:53 +00:00
sprintf ( xorriso - > info_text , " No %s drive acquired %s " ,
2010-05-15 18:48:10 +00:00
( flag & 2 ? " output " : " input " ) , attempt ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
}
if ( * dinfo = = NULL )
return ( 0 ) ;
* drive = ( * dinfo ) [ 0 ] . drive ;
if ( flag & 1 ) {
ret = burn_drive_get_drive_role ( * drive ) ;
if ( ret ! = 1 ) {
sprintf ( xorriso - > info_text ,
" Output device is not an MMC drive. Desired operation does not apply. " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " NOTE " , 0 ) ;
return ( 2 ) ;
}
}
return ( ( * drive ) ! = NULL ) ;
}
2012-10-24 09:59:13 +00:00
int Xorriso_pretend_full_disc ( struct XorrisO * xorriso , int flag )
{
int ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to let libburn pretend having a closed medium " , 2 ) ;
if ( ret < = 0 )
return ( ret ) ;
2014-05-03 11:50:03 +00:00
ret = isoburn_disc_pretend_full_uncond ( drive ) ;
2012-10-24 09:59:13 +00:00
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ret < = 0 ) {
sprintf ( xorriso - > info_text ,
" Failed to let libburn pretend having a closed medium " ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " FAILURE " , 0 ) ;
return ( 0 ) ;
}
return ( 1 ) ;
}
2016-03-18 13:55:09 +00:00
int Xorriso_scsi_dev_family ( struct XorrisO * xorriso , int flag )
{
burn_preset_device_open ( xorriso - > drives_exclusive | ( xorriso - > linux_scsi_dev_family < < 2 ) , 0 , 0 ) ;
return ( 1 ) ;
}
2016-07-31 07:38:41 +00:00
int Xorriso_use_immed_bit ( struct XorrisO * xorriso , int flag )
{
int enable = 1 , ret ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
/* It is not an error if no drive is acquired.
Xorriso_drive_aquire ( ) will apply use_immed_bit .
*/
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to control use of Immed bit " , 2 | 16 ) ;
if ( ret < 0 )
return ( ret ) ;
if ( ret = = 0 )
return ( 1 ) ;
if ( xorriso - > use_immed_bit = = - 1 ) {
enable = 0 ;
} else if ( xorriso - > use_immed_bit = = 1 ) {
enable = 1 ;
} else if ( xorriso - > use_immed_bit = = 0 ) {
/* obtain default value as determined after drive aquiration */
if ( xorriso - > use_immed_bit_default = = 0 )
return ( 1 ) ;
enable = ( xorriso - > use_immed_bit_default > 0 ) ;
}
burn_drive_set_immed ( drive , enable ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
return ( 1 ) ;
}
2024-03-21 08:44:51 +00:00
int Xorriso_obtain_indev_readsize ( struct XorrisO * xorriso , off_t * blocks ,
2020-12-05 08:53:59 +00:00
int flag )
{
2024-03-21 08:44:51 +00:00
int ret ;
off_t num_data ;
2020-12-05 08:53:59 +00:00
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
enum burn_disc_status s ;
* blocks = 0 ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" on attempt to determine readable size " , 0 ) ;
if ( ret < = 0 )
return ( 0 ) ;
s = isoburn_disc_get_status ( drive ) ;
if ( s = = BURN_DISC_BLANK )
return ( 1 ) ;
2024-03-21 08:44:51 +00:00
ret = burn_get_read_capacity_v2 ( drive , & num_data , 0 ) ;
2020-12-05 08:53:59 +00:00
if ( ret < = 0 )
return ( 0 ) ;
* blocks = num_data ;
return ( 1 ) ;
}
2022-09-20 08:28:25 +00:00
/* @param flag bit0= as_mkisofs, else cmd
*/
int Xorriso_feature_to_cmd ( struct XorrisO * xorriso , char * name , char * value ,
int flag )
{
int i , as_m ;
double val_num = - 123456789 ;
static char * ignored_names [ ] = { " size " , " eltorito " , " tree_loaded " ,
" tree_loaded_text " , " rr_loaded " , " aaip " ,
" relaxed_vol_atts " , " rrip_1_10_px_ino " ,
" " } ;
sscanf ( value , " %lf " , & val_num ) ;
for ( i = 0 ; ignored_names [ i ] [ 0 ] ! = 0 ; i + + )
if ( strcmp ( name , ignored_names [ i ] ) = = 0 )
return ( 0 ) ;
as_m = flag & 1 ;
if ( strcmp ( name , " iso_level " ) = = 0 ) {
if ( as_m ) {
sprintf ( xorriso - > result_line , " -iso-level %s " , value ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance iso_9660_level=%s " , value ) ;
}
} else if ( strcmp ( name , " rockridge " ) = = 0 ) {
if ( as_m ) {
if ( val_num > 0.0 )
sprintf ( xorriso - > result_line , " -R " ) ;
else
sprintf ( xorriso - > result_line , " --norock " ) ;
} else {
sprintf ( xorriso - > result_line , " -rockridge %s " ,
val_num > 0.0 ? " on " : " off " ) ;
}
} else if ( strcmp ( name , " joliet " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -J " ) ;
} else {
sprintf ( xorriso - > result_line , " -joliet %s " ,
val_num > 0.0 ? " on " : " off " ) ;
}
} else if ( strcmp ( name , " iso1999 " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -iso-level 4 " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance iso_9660_1999%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " untranslated_name_len " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -untranslated_name_len %s " , value ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance untranslated_name_len=%s " ,
value ) ;
}
} else if ( strcmp ( name , " allow_dir_id_ext " ) = = 0 ) {
if ( as_m ) {
if ( val_num > 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -disallow_dir_id_ext " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance allow_dir_id_ext%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " omit_version_numbers " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -N " ) ;
} else {
if ( val_num < = 0.0 )
sprintf ( xorriso - > result_line ,
" -compliance omit_version_off:only_iso_version_off " ) ;
else if ( val_num = = 2.0 )
sprintf ( xorriso - > result_line ,
" -compliance omit_version_off:only_iso_version " ) ;
else
sprintf ( xorriso - > result_line ,
" -compliance omit_version:only_iso_version_off " ) ;
}
} else if ( strcmp ( name , " allow_deep_paths " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -D " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance deep_paths%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " allow_longer_paths " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -U " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance long_paths%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " allow_full_ascii " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -U " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance full_ascii%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " max_37_char_filenames " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -max-iso9660-filenames " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance long_names%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " no_force_dots " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -d " ) ;
} else {
sprintf ( xorriso - > result_line ,
" -compliance no_force_dots%s:no_j_force_dots%s " ,
( ( int ) val_num ) & 1 ? " " : " _off " ,
( ( int ) val_num ) & 2 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " allow_lowercase " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -allow-lowercase " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance lowercase%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " joliet_longer_paths " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -joliet-long " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance joliet_long_paths%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " joliet_long_names " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -joliet-long " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance joliet_long_names%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " joliet_utf16 " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " -joliet-utf16 " ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance joliet_utf16%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " rrip_version_1_10 " ) = = 0 ) {
if ( as_m ) {
return ( 0 ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance %s_rr " ,
val_num > 0.0 ? " old " : " new " ) ;
}
} else if ( strcmp ( name , " aaip_susp_1_10 " ) = = 0 ) {
if ( as_m ) {
return ( 0 ) ;
} else {
sprintf ( xorriso - > result_line , " -compliance aaip_susp_1_10%s " ,
val_num > 0.0 ? " " : " _off " ) ;
}
} else if ( strcmp ( name , " record_md5_session " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " --md5 " ) ;
} else {
sprintf ( xorriso - > result_line , " -md5 %s " , val_num > 0.0 ? " on " : " off " ) ;
}
} else if ( strcmp ( name , " record_md5_files " ) = = 0 ) {
if ( as_m ) {
if ( val_num < = 0.0 )
return ( 0 ) ;
sprintf ( xorriso - > result_line , " --md5 " ) ;
} else {
sprintf ( xorriso - > result_line , " -md5 %s " , val_num > 0.0 ? " on " : " off " ) ;
}
} else {
sprintf ( xorriso - > info_text , " Program error: unexpected feature name '%s' " ,
name ) ;
Xorriso_msgs_submit ( xorriso , 0 , xorriso - > info_text , 0 , " DEBUG " , 0 ) ;
return ( - 1 ) ;
}
return ( 1 ) ;
}
2022-10-07 09:55:10 +00:00
/* @param flag bit0= do not print xorriso->result_line, but accumulate it
*/
2022-09-20 08:28:25 +00:00
int Xorriso_assess_written_features ( struct XorrisO * xorriso , char * mode ,
int flag )
{
int ret , l , ftext_l , replay_count = 0 , max_line_size = 2 * SfileadrL ;
struct burn_drive_info * dinfo ;
struct burn_drive * drive ;
enum burn_disc_status s ;
struct isoburn_read_opts * ropts = NULL ;
IsoReadImageFeatures * features = NULL ;
struct isoburn_imgen_opts * imgen_opts = NULL ;
char * ftext = NULL , * cpt , * npt , * ept , * prev_line = NULL , * cmd_line = NULL ;
2022-10-07 09:55:10 +00:00
char * result_acc = NULL ;
2022-09-20 08:28:25 +00:00
static char * tree_loaded_names [ 3 ] = { " ISO9660 " , " Joliet " , " ISO9660:1999 " } ;
int tree_loaded_names_max = 2 ;
Xorriso_alloc_meM ( prev_line , char , max_line_size ) ;
Xorriso_alloc_meM ( cmd_line , char , max_line_size ) ;
2022-10-07 09:55:10 +00:00
if ( flag & 1 ) {
Xorriso_alloc_meM ( result_acc , char , 10 * SfileadrL ) ;
result_acc [ 0 ] = 0 ;
}
2022-09-20 08:28:25 +00:00
prev_line [ 0 ] = 0 ;
ret = Xorriso_get_drive_handles ( xorriso , & dinfo , & drive ,
" when assessing written features " , 0 ) ;
if ( ret < = 0 )
{ ret = 0 ; goto ex ; }
s = isoburn_disc_get_status ( drive ) ;
if ( s ! = BURN_DISC_APPENDABLE & & s ! = BURN_DISC_FULL ) {
Xorriso_msgs_submit ( xorriso , 0 ,
" The disc in the input drive offers no readable content " , 0 , " NOTE " , 0 ) ;
ret = 2 ; goto ex ;
}
2022-10-07 09:55:10 +00:00
ret = Xorriso_make_read_options ( xorriso , drive , & ropts , 1 ) ;
2022-09-20 08:28:25 +00:00
if ( ret < = 0 )
goto ex ;
ret = isoburn_assess_written_features ( drive , ropts , & features , & imgen_opts ,
0 ) ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
/* <<< Resetting to normal thresholds, after Xorriso_make_read_options */
if ( xorriso - > img_read_error_mode > 0 )
Xorriso_set_abort_severity ( xorriso , 0 ) ;
if ( ret < = 0 )
{ ret = 0 ; goto ex ; }
ret = iso_read_image_features_text ( features , 1 , & ftext ) ;
if ( ret < 0 )
{ ret = 0 ; goto ex ; }
/* print results, depending on mode */
ftext_l = strlen ( ftext ) ;
for ( cpt = ftext ; cpt - ftext < ftext_l ; cpt + = l + 1 ) {
npt = strchr ( cpt , ' \n ' ) ;
if ( npt = = NULL )
l = strlen ( cpt ) ;
else
l = npt - cpt ;
cpt [ l ] = 0 ;
ept = strchr ( cpt , ' = ' ) ;
if ( ept = = NULL )
continue ;
if ( strcmp ( mode , " cmd " ) = = 0 | | strcmp ( mode , " replay " ) = = 0 | |
strcmp ( mode , " as_mkisofs " ) = = 0 ) {
* ept = 0 ;
ret = Xorriso_feature_to_cmd ( xorriso , cpt , ept + 1 ,
strcmp ( mode , " as_mkisofs " ) = = 0 ) ;
if ( ret < = 0 )
continue ;
} else { /* "plain" and any other */
strcpy ( xorriso - > result_line , " Indev feature: " ) ;
if ( strncmp ( cpt , " tree_loaded= " , 12 ) = = 0 ) {
sprintf ( xorriso - > result_line + strlen ( xorriso - > result_line ) ,
" tree_loaded=%d " , xorriso - > tree_loaded ) ;
} else if ( strncmp ( cpt , " tree_loaded_text= " , 17 ) = = 0 ) {
if ( xorriso - > tree_loaded > = 0 & &
xorriso - > tree_loaded < = tree_loaded_names_max )
sprintf ( xorriso - > result_line + strlen ( xorriso - > result_line ) ,
" tree_loaded_text=%s " ,
tree_loaded_names [ xorriso - > tree_loaded ] ) ;
} else if ( strncmp ( cpt , " rr_loaded= " , 10 ) = = 0 ) {
sprintf ( xorriso - > result_line + strlen ( xorriso - > result_line ) ,
" rr_loaded=%d " , xorriso - > rr_loaded ) ;
} else {
strcat ( xorriso - > result_line , cpt ) ;
}
}
/* Truncate to plausible length */
xorriso - > result_line [ max_line_size - 1 ] = 0 ;
if ( strcmp ( xorriso - > result_line , prev_line ) = = 0 )
continue ;
strcpy ( prev_line , xorriso - > result_line ) ;
if ( strcmp ( mode , " replay " ) = = 0 ) {
/* Perform result_line as command */
strcpy ( cmd_line , xorriso - > result_line ) ;
ret = Xorriso_execute_option ( xorriso , cmd_line , ( 1 < < 16 ) ) ;
if ( ret < = 0 ) {
/* >>> ??? what to do on error */ ;
}
replay_count + + ;
} else {
strcat ( xorriso - > result_line , " \n " ) ;
2022-10-07 09:55:10 +00:00
if ( flag & 1 ) {
if ( strlen ( result_acc ) + strlen ( xorriso - > result_line ) < 10 * SfileadrL )
strcat ( result_acc , xorriso - > result_line ) ;
} else {
Xorriso_result ( xorriso , 0 ) ;
}
2022-09-20 08:28:25 +00:00
}
}
if ( strcmp ( mode , " replay " ) = = 0 ) {
sprintf ( xorriso - > info_text ,
" -assess_indev_features replay : Number of performed commands: %d \n " ,
replay_count ) ;
Xorriso_info ( xorriso , 0 ) ;
}
2022-10-07 09:55:10 +00:00
if ( flag & 1 )
strcpy ( xorriso - > result_line , result_acc ) ;
2022-09-20 08:28:25 +00:00
ret = 1 ;
ex : ;
Xorriso_process_msg_queues ( xorriso , 0 ) ;
if ( ropts ! = NULL )
isoburn_ropt_destroy ( & ropts , 0 ) ;
if ( features ! = NULL )
iso_read_image_features_destroy ( features ) ;
if ( imgen_opts ! = NULL )
isoburn_igopt_destroy ( & imgen_opts , 0 ) ;
Xorriso_free_meM ( ftext ) ;
2022-10-07 09:55:10 +00:00
Xorriso_free_meM ( result_acc ) ;
2022-09-20 08:28:25 +00:00
Xorriso_free_meM ( cmd_line ) ;
Xorriso_free_meM ( prev_line ) ;
return ( ret ) ;
}