Adapted media evaluation to CD peculiarities

This commit is contained in:
Thomas Schmitt 2008-08-11 20:17:09 +00:00
parent 0f0a2e4bb5
commit 235cbe3dfe
5 changed files with 633 additions and 39 deletions

View File

@ -123,13 +123,13 @@ or
/* The official xorriso options API. "No shortcuts" */
#include "xorriso.h"
/* The inner isofs- and burn-library interface */
#include "xorrisoburn.h"
/* The inner description of XorrisO */
#define Xorriso_is_xorriso_selF 1
#include "xorriso_private.h"
/* The inner isofs- and burn-library interface */
#include "xorrisoburn.h"
/* ------------------------------------------------------------------------ */
@ -2945,6 +2945,12 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
strcpy(name, "good");
else if(quality == Xorriso_read_quality_sloW)
strcpy(name, "slow");
else if(quality == Xorriso_read_quality_partiaL)
strcpy(name, "partial");
else if(quality == Xorriso_read_quality_valiD)
strcpy(name, "valid");
else if(quality == Xorriso_read_quality_invaliD)
strcpy(name, "invalid");
else if(quality == Xorriso_read_quality_off_tracK)
strcpy(name, "off track");
else if(quality == Xorriso_read_quality_untesteD)
@ -2959,6 +2965,266 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
/* ---------------------------- End SpotlisT ------------------------------ */
/* ---------------------------- SectorbitmaP ------------------------------ */
struct SectorbitmaP {
int sectors;
int sector_size;
unsigned char *map;
int map_size;
};
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag);
int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size,
int flag)
{
struct SectorbitmaP *m;
m= TSOB_FELD(struct SectorbitmaP,1);
if(m==NULL)
return(-1);
*o= m;
m->sectors= sectors;
m->sector_size= sector_size;
m->map= NULL;
m->map_size= sectors / 8 + 1;
m->map= calloc(m->map_size, 1);
if(m->map == NULL)
goto failure;
return(1);
failure:;
Sectorbitmap_destroy(o, 0);
return(-1);
}
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag)
{
if((*o) == NULL)
return(0);
if((*o)->map != NULL)
free((char *) (*o)->map);
free((char *) *o);
*o= NULL;
return(1);
}
int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg,
int *os_errno, int flag)
{
int ret, fd= -1, sectors, sector_size, i, todo, map_size;
unsigned char *map;
unsigned char buf[1024];
*os_errno= 0;
if(msg != NULL)
msg[0]= 0;
fd= open(path, O_RDONLY);
if(fd == -1) {
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Cannot open path ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
return(0);
}
ret= read(fd, buf, 32);
if(ret < 32) {
wrong_filetype:;
if(ret == -1)
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Not a sector bitmap file: ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
ret= 0; goto ex;
}
if(strncmp((char *) buf, "xorriso sector bitmap v1 ", 32) != 0)
{ret= 0; goto wrong_filetype;}
ret= read(fd, buf, 8);
if(ret < 4)
goto wrong_filetype;
sectors= (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
sector_size= (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
if(sectors <= 0 || sector_size <= 0)
goto wrong_filetype;
ret= Sectorbitmap_new(o, sectors, sector_size, 0);
if(ret <= 0) {
if(msg != NULL)
sprintf(msg, "Cannot allocate bitmap memory for %d sectors", sectors);
ret= -1; goto ex;
}
map= (*o)->map;
map_size= (*o)->map_size;
for(i= 0; i < map_size; i+= sizeof(buf)) {
todo= sizeof(buf);
if(i + todo > map_size)
todo= map_size - i;
ret= read(fd, buf, todo);
if(ret != todo)
goto wrong_filetype;
memcpy(map + i, buf, todo);
}
ret= 1;
ex:;
if(fd != -1)
close(fd);
if(ret <= 0)
Sectorbitmap_destroy(o, 0);
return(ret);
}
int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *msg,
int *os_errno, int flag)
{
int ret, fd= -1, j;
unsigned char buf[32];
*os_errno= 0;
fd= open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if(fd == -1) {
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Cannot open path ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
return(0);
}
ret= write(fd, "xorriso sector bitmap v1 ", 32);
if(ret != 32) {
cannot_write:;
*os_errno= errno;
if(msg != NULL) {
strcpy(msg, "Cannot write to ");
Text_shellsafe(path, msg+strlen(msg), 0);
}
ret= 0; goto ex;
}
for(j= 0; j < 4; j++) {
buf[j]= o->sectors >> (24 - j * 8);
buf[j+4]= o->sector_size >> (24 - j * 8);
}
ret= write(fd, buf, 8);
if(ret != 8)
goto cannot_write;
ret= write(fd, o->map, o->map_size);
if(ret != o->map_size)
goto cannot_write;
ret= 1;
ex:;
if(fd != -1)
close(fd);
return(ret);
}
/* @param flag bit0= sector bit value
*/
int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag)
{
if(sector < 0 || sector >= o->sectors)
return(0);
if(flag & 1)
o->map[sector / 8]|= 1 << (sector % 8);
else
o->map[sector / 8]&= ~(1 << (sector % 8));
return(1);
}
/* @param flag bit0= sector bit value
*/
int Sectorbitmap_set_range(struct SectorbitmaP *o,
int start_sector, int sectors, int flag)
{
int start_i, end_i, i;
unsigned char value;
if(start_sector < 0 || start_sector + sectors > o->sectors || sectors < 1)
return(0);
if(flag & 1)
value= ~0;
else
value= 0;
start_i= start_sector / 8;
end_i= (start_sector + sectors - 1) / 8;
for(i= start_sector; i / 8 == start_i && i < start_sector + sectors; i++)
Sectorbitmap_set(o, i, flag & 1);
for(i= start_i + 1; i < end_i; i++)
o->map[i]= value;
if(end_i > start_i)
for(i= end_i * 8; i < start_sector + sectors; i++)
Sectorbitmap_set(o, i, flag & 1);
return(1);
}
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag)
{
if(sector < 0 || sector >= o->sectors)
return(0);
return(!! (o->map[sector / 8] & (1 << (sector % 8))));
}
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag)
{
*sectors= o->sectors;
*sector_size= o->sector_size;
return(1);
}
int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
int flag)
{
int i, run_start, run_value, start_sec, limit_sec, start_aligned;
int end_complete;
if(from->sectors * from->sector_size > to->sectors * to->sector_size)
return(-1);
if(from->sector_size == to->sector_size) {
for(i= 0; i < from->map_size; i++)
to->map[i]= from->map[i];
return(1);
}
run_start= 0;
run_value= Sectorbitmap_is_set(from, 0, 0);
for(i= 1; i <= from->sectors; i++) {
if(i < from->sectors)
if(Sectorbitmap_is_set(from, i, 0) == run_value)
continue;
start_sec= run_start * from->sector_size / to->sector_size;
start_aligned=
(start_sec * to->sector_size == run_start * from->sector_size);
limit_sec= i * from->sector_size / to->sector_size;
end_complete= (limit_sec * to->sector_size == i * from->sector_size);
if(run_value) {
if(!start_aligned)
start_sec++;
} else {
if(!end_complete)
limit_sec++;
}
if(start_sec < limit_sec)
Sectorbitmap_set_range(to, start_sec, limit_sec - 1 - start_sec,
!!run_value);
run_value= !run_value;
run_start= i;
}
return(1);
}
/* -------------------------- End SectorbitmaP ---------------------------- */
/* ---------------------------- CheckmediajoB ----------------------------- */
int Checkmediajob_new(struct CheckmediajoB **o, int flag)
@ -2972,10 +3238,15 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag)
m->min_lba= -1;
m->max_lba= -1;
m->min_block_size= 16;
m->mode= 1;
m->mode= 0;
m->start_time= time(NULL);
m->time_limit= -1;
m->item_limit= -1;
m->data_to_path[0]= 0;
m->data_to_fd= -1;
m->sector_map_path[0]= 0;
m->sector_map= NULL;
m->retry= 0;
return(1);
}
@ -2984,6 +3255,7 @@ int Checkmediajob_destroy(struct CheckmediajoB **o, int flag)
{
if((*o) == NULL)
return(0);
Sectorbitmap_destroy(&((*o)->sector_map), 0);
free((char *) *o);
*o= NULL;
return(1);
@ -8376,7 +8648,70 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
return(1);
}
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SpotlisT *spotlist,
int sector_size,
struct SectorbitmaP **map,
int flag)
{
struct SectorbitmaP *m;
int map_sectors= -1, map_sector_size= -1;
int list_sectors, list_blocks, sector_blocks;
int replace_map= 0, count, i, lba, blocks, quality, ret;
sector_blocks= sector_size / 2048;
if(*map != NULL)
Sectorbitmap_get_layout(*map, &map_sectors, &map_sector_size, 0);
count= Spotlist_count(spotlist, 0);
list_blocks= 0;
for(i= 0; i < count; i++) {
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0)
continue;
if(lba + blocks > list_blocks)
list_blocks= lba + blocks;
}
/* >>> ??? insist in list_blocks % sector_blocks == 0 */
list_sectors= list_blocks / sector_blocks;
if(list_sectors * sector_blocks < list_blocks)
list_sectors++;
if(*map != NULL && map_sectors * (map_sector_size / 2048) >= list_blocks &&
map_sector_size == sector_size)
m= *map;
else {
ret= Sectorbitmap_new(&m, list_sectors, sector_size, 0);
if(ret <= 0)
return(-1);
replace_map= 1;
if(*map != NULL) {
ret= Sectorbitmap_copy(*map, m, 0);
if(ret <= 0) {
Sectorbitmap_destroy(&m, 0);
return(0);
}
}
}
count= Spotlist_count(spotlist, 0);
for(i= 0; i < count; i++) {
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0)
continue;
Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks,
quality >= Xorriso_read_quality_valiD);
}
if(replace_map) {
Sectorbitmap_destroy(map, 0);
*map= m;
}
return(1);
}
/* ---------------------------- Options API ------------------------ */
@ -8896,7 +9231,11 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
goto ex;
for(i= old_idx; i < end_idx; i++) {
if(strncmp(argv[i], "max_lba=", 8) == 0 ||
if(strncmp(argv[i], "data_to=", 8) == 0) {
ret= Sfile_str(job->data_to_path, argv[i] + 8, 0);
if(ret <= 0)
goto ex;
} else if(strncmp(argv[i], "max_lba=", 8) == 0 ||
strncmp(argv[i], "min_lba=", 8) == 0) {
num= -1;
sscanf(argv[i] + 8, "%lf", &num);
@ -8906,6 +9245,19 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
job->max_lba= num;
else
job->min_lba= num;
} else if(strncmp(argv[i], "retry=", 6) == 0) {
if(strcmp(argv[i] + 6, "on") == 0)
job->retry= 1;
else if(strcmp(argv[i] + 6, "off") == 0)
job->retry= -1;
else if(strcmp(argv[i] + 6, "default") == 0)
job->retry= 0;
else
goto unknown_value;
} else if(strncmp(argv[i], "sector_map=", 11) == 0) {
ret= Sfile_str(job->sector_map_path, argv[i] + 11, 0);
if(ret <= 0)
goto ex;
} else if(strncmp(argv[i], "time_limit=", 11) == 0 ||
strncmp(argv[i], "item_limit=", 11) == 0 ) {
num= -1;
@ -8916,8 +9268,20 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
job->time_limit= num;
else
job->item_limit= num;
} else if(strncmp(argv[i], "what=", 5) == 0) {
if(strcmp(argv[i]+5, "tracks") == 0)
job->mode= 0;
else if(strcmp(argv[i]+5, "disc")== 0)
job->mode= 1;
else {
unknown_value:;
sprintf(xorriso->info_text,
"-check_media: Unknown value with option %s", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
sprintf(xorriso->info_text, "-check_media: Unknown option %s", argv[i]);
sprintf(xorriso->info_text, "-check_media: Unknown option '%s'", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
@ -10449,7 +10813,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -check_media [options] --",
" Try to read data blocks from media and report about the",
" outcome. Several options modify the behavior:",
" min_lba= , max_lba= , time_limit= , item_limit=",
" min_lba= , max_lba= , time_limit= , item_limit= ,",
" data_to= ,",
"",
"Compatibility emulation (argument list may be ended by --):",
" -as mkisofs [-help|-version|-o|-R|-J|-V|-P|-f|-m|-exclude-list|-no-pad|",

View File

@ -50,6 +50,7 @@ struct ExclusionS; /* List of -not_* conditions */
struct PermiteM; /* Stack of temporarily altered access permissions */
struct SpotlisT; /* List of intervals with different read qualities */
struct CheckmediajoB; /* Parameters for Xorriso_check_media() */
struct SectorbitmaP; /* Distiniction between valid and invalid sectors */
/* maximum number of history lines to be reported with -status:long_history */
@ -453,6 +454,11 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag);
int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag);
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SpotlisT *spotlist,
int sector_size,
struct SectorbitmaP **map,
int flag);
int Sfile_str(char target[SfileadrL], char *source, int flag);
@ -632,9 +638,12 @@ char *Spotlist__quality_name(int quality, char name[80], int flag);
#define Xorriso_read_quality_gooD 0x7fffffff
#define Xorriso_read_quality_sloW 0x40000000
#define Xorriso_read_quality_off_tracK 0x08000000
#define Xorriso_read_quality_untesteD 0x04000000
#define Xorriso_read_quality_sloW 0x60000000
#define Xorriso_read_quality_partiaL 0x50000000
#define Xorriso_read_quality_valiD 0x40000000
#define Xorriso_read_quality_invaliD 0x3fffffff
#define Xorriso_read_quality_off_tracK 0x20000000
#define Xorriso_read_quality_untesteD 0x10000000
#define Xorriso_read_quality_unreadablE 0x00000000
@ -642,5 +651,22 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag);
int Checkmediajob_destroy(struct CheckmediajoB **o, int flag);
int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size,
int flag);
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag);
int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg,
int *os_errno, int flag);
int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *msg,
int *os_errno, int flag);
int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_set_range(struct SectorbitmaP *o,
int start_sector, int sectors, int flag);
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag);
#endif /* Xorriso_private_includeD */

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.08.09.161311"
#define Xorriso_timestamP "2008.08.11.201604"

View File

@ -6557,18 +6557,21 @@ int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag)
return(1);
}
/* @return <=0 error, 1= done, 2= aborted due to limit
*/
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
struct CheckmediajoB *job,
int from_lba, int block_count,
int read_chunk, int min_block_size, int flag)
{
int i, ret, total_count= 0;
int prev_quality= -1, quality= -1;
int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd;
int start_sec, end_sec, first_value;
char profile_name[80];
int start_lba= 0;
struct burn_drive *drive;
struct burn_drive_info *dinfo;
char data[64*1024];
char data[64*1024], sfe[5*SfileadrL];
off_t data_count, to_read;
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
@ -6576,9 +6579,25 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
"on attempt to check media readability", 0);
if(ret<=0)
goto ex;
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
if(ret > 0)
if(profile_no >= 0x08 && profile_no <= 0x0a)
is_cd= 1;
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;
start_lba= from_lba;
for(i= 0; i < block_count; i+= read_chunk) {
to_read= read_chunk;
for(i= 0; i < block_count; i+= to_read) {
skip_reading= 0;
if(job->item_limit > 0 &&
Spotlist_count(spotlist, 0) + 2 >= job->item_limit) {
sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d",
@ -6599,7 +6618,7 @@ abort_check:;
if(ret <= 0)
goto ex;
}
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - 1,
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i,
Xorriso_read_quality_untesteD, 0);
if(ret > 0)
ret= 2;
@ -6608,27 +6627,103 @@ abort_check:;
to_read= read_chunk;
if(i + to_read > block_count)
to_read= block_count - i;
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
to_read * (off_t) 2048, &data_count, 4);
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);
quality= Xorriso_read_quality_unreadablE;
if(read_chunk > min_block_size) {
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.
*/
if(to_read > 2)
to_read-= 2;
else if(to_read > 1)
to_read--;
}
/* >>> evaluate min blocks */;
#ifdef NIX
/* >>> this is not yet suitable for min_block_size */
#endif
if(sector_size == read_chunk && from_lba % read_chunk == 0) {
if(Sectorbitmap_is_set(job->sector_map, (i + from_lba) / read_chunk, 0)) {
quality= Xorriso_read_quality_valiD;
skip_reading= 1;
}
} else if(sector_size > 0) {
start_sec= (i + from_lba) / sector_size;
end_sec= (i + to_read + from_lba) / sector_size;
first_value= Sectorbitmap_is_set(job->sector_map, start_sec, 0);
for(j= start_sec; j < end_sec; j++)
if(Sectorbitmap_is_set(job->sector_map, j, 0) != first_value)
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);
} else {
quality= Xorriso_read_quality_gooD;
data_count= 0;
pre_read_time= Sfile_microtime(0);
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
to_read * (off_t) 2048, &data_count, 4 * !retry);
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);
/* >>> find better threshold than 1.0 */
if(data_count > 0 && retry) {
if(prev_quality >= 0) {
ret= Spotlist_add_item(spotlist, start_lba,
i + from_lba - start_lba, prev_quality, 0);
if(ret <= 0)
goto ex;
}
ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048,
Xorriso_read_quality_partiaL, 0);
if(ret <= 0)
goto ex;
start_lba= i + from_lba + data_count / 2048;
prev_quality= Xorriso_read_quality_unreadablE;
}
quality= Xorriso_read_quality_unreadablE;
if(time_diff > 1.0 && i > 0)
quality= Xorriso_read_quality_sloW;
#ifdef NIX
if(read_chunk > min_block_size) {
/* >>> evaluate min blocks */;
}
#endif
} else {
quality= Xorriso_read_quality_gooD;
/* >>> find better threshold than 1.0 */
if(time_diff > 1.0 && i > 0)
quality= Xorriso_read_quality_sloW;
}
if(data_count > 0) {
if(job->data_to_fd >= 0) {
ret= lseek(job->data_to_fd, ((off_t) (i + from_lba)) * (off_t) 2048,
SEEK_SET);
if(ret == -1) {
failed_to_write:;
sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of %s",
(int) data_count, i + from_lba,
Text_shellsafe(job->data_to_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
"FAILURE", 0);
{ret= 0; goto ex;}
}
ret= write(job->data_to_fd, data, data_count);
if(ret == -1)
goto failed_to_write;
}
}
}
if(quality != prev_quality) {
if(prev_quality >= 0) {
@ -6669,10 +6764,17 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
struct CheckmediajoB *job, int flag)
{
int media_blocks= 0, read_chunk= 16, ret, mode, min_block_size, start_lba= 0;
int blocks;
int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba;
int num_sessions, num_tracks, declare_untested= 0, sector_size, count;
int lba, quality;
char sfe[5*SfileadrL];
struct burn_drive *drive;
struct burn_drive_info *dinfo;
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;
*spotlist= NULL;
@ -6692,6 +6794,30 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
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;
}
}
}
if(job->data_to_path[0]) {
job->data_to_fd= open(job->data_to_path, O_WRONLY | O_CREAT,
S_IRUSR | S_IWUSR);
if(job->data_to_fd == -1) {
sprintf(xorriso->info_text, "Cannot open path %s",
Text_shellsafe(job->data_to_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
{ret= 0; goto ex;}
}
}
Xorriso_pacifier_reset(xorriso, 0);
job->start_time= time(NULL);
mode= job->mode;
@ -6705,11 +6831,55 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
if(ret <= 0)
goto ex;
} else if(mode == 0) {
} else if(mode == 0) { /* track by track */
isoburn_disc= isoburn_toc_drive_get_disc(drive);
if(isoburn_disc == NULL)
goto no_content_visible;
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;
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;
/* >>> track by track */;
if(track_lba < start_lba) {
track_blocks-= start_lba - track_lba;
track_lba= start_lba;
}
if(track_blocks <= 0)
continue;
if(declare_untested) {
ret= Spotlist_add_item(*spotlist, track_lba, track_blocks,
Xorriso_read_quality_untesteD, 0);
if(ret <= 0)
goto ex;
} else {
ret= Xorriso_check_interval(xorriso, *spotlist, job,
track_lba, track_blocks,
read_chunk, min_block_size, 0);
if(ret <= 0)
goto ex;
if(ret == 2)
declare_untested= 1;
}
}
}
} else if(mode == 1) {
} else if(mode == 1) { /* isoburn disc capacity */
isoburn_disc= isoburn_toc_drive_get_disc(drive);
if(isoburn_disc == NULL) {
no_content_visible:;
@ -6738,6 +6908,32 @@ no_content_visible:;
xorriso->pacifier_count, xorriso->pacifier_total, "", 1);
ret= 1;
ex:;
if(job->data_to_fd != -1)
close(job->data_to_fd);
if(ret > 0 && job->sector_map_path[0]) {
sector_size= read_chunk * 2048;
count= Spotlist_count(*spotlist, 0);
for(i= 0; i < count; i++) {
ret= Spotlist_get_item(*spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0)
continue;
if(lba % read_chunk) {
sector_size= 2048;
break;
}
}
ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, sector_size,
&(job->sector_map), 0);
if(ret > 0) {
ret= Sectorbitmap_to_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);
}
}
}
if(ret < 0)
Spotlist_destroy(spotlist, 0);
return(ret);

View File

@ -14,9 +14,6 @@
#ifndef Xorrisoburn_includeD
#define Xorrisoburn_includeD yes
struct XorrisO;
struct FindjoB;
struct SpotlisT;
/* The minimum version of libisoburn to be used with this version of xorriso
*/
@ -297,6 +294,16 @@ struct CheckmediajoB {
int item_limit; /* Maximum number of media check list items as result */
char data_to_path[SfileadrL];
int data_to_fd;
char sector_map_path[SfileadrL];
struct SectorbitmaP *sector_map;
int retry; /* -1= only try full read_chunk, 1=retry with 2k blocks
0= retry with CD, full chunk else
*/
};
int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,