Try to read header chain from alleged -ROM media (e.g. DVD+RW in -ROM drive)
This commit is contained in:
parent
4c55ac810d
commit
0612232c5c
@ -241,16 +241,25 @@ int isoburn_is_intermediate_dvd_rw(struct burn_drive *d, int flag)
|
||||
|
||||
/** Examines the media and sets appropriate emulation if needed.
|
||||
@param flag bit0= pretent blank on overwriteable media
|
||||
bit3= if the drive reports a -ROM profile then try to read
|
||||
table of content by scanning for ISO image headers.
|
||||
*/
|
||||
static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d,
|
||||
int flag)
|
||||
{
|
||||
int ret, lba, nwa;
|
||||
int ret, lba, nwa, profile, readonly= 0;
|
||||
struct burn_multi_caps *caps= NULL;
|
||||
char profile_name[80];
|
||||
|
||||
profile_name[0]= 0;
|
||||
ret= burn_disc_get_profile(d, &profile, profile_name);
|
||||
if(ret<=0)
|
||||
profile= 0x00;
|
||||
ret= burn_disc_get_multi_caps(d, BURN_WRITE_NONE, &caps, 0);
|
||||
if(ret<0) /* == 0 is read-only media, but it is too early to reject it here */
|
||||
goto ex;
|
||||
if(ret==0)
|
||||
readonly= 1;
|
||||
ret= isoburn_new(o, 0);
|
||||
if(ret<=0)
|
||||
goto ex;
|
||||
@ -286,10 +295,27 @@ static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d,
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* >>> recognize unsuitable media (but allow read-only media) */;
|
||||
/* >>> recognize unsuitable media (but allow read-only media) */;
|
||||
|
||||
if(readonly) {
|
||||
/* This might be overwriteable media in a -ROM drive */
|
||||
ret= isoburn_emulate_toc(d, 1);
|
||||
if(ret<0)
|
||||
goto ex;
|
||||
if(ret==0 && profile !=0x08 && (flag&8)) {
|
||||
/* This might also be multi-session media which do not
|
||||
get shown with a decent TOC.
|
||||
CD-R TOC (profile 0x08) can be trusted. Others not.
|
||||
*/
|
||||
/* do a scan search of ISO headers */
|
||||
ret= isoburn_emulate_toc(d, 1|2);
|
||||
if(ret<0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
#ifdef Hardcoded_cd_rW
|
||||
(*o)->nwa= Hardcoded_cd_rw_nwA;
|
||||
#else
|
||||
@ -312,6 +338,10 @@ ex:
|
||||
bit1= regard overwriteable media as blank
|
||||
bit2= if the drive is a regular disk file: truncate it to
|
||||
the write start address
|
||||
bit3= if the drive reports a -ROM profile then try to read
|
||||
table of content by scanning for ISO image headers.
|
||||
(depending on media type and drive state this might
|
||||
help or it might make the resulting toc even worse)
|
||||
*/
|
||||
int isoburn_drive_aquire(struct burn_drive_info *drive_infos[],
|
||||
char *adr, int flag)
|
||||
@ -333,7 +363,8 @@ int isoburn_drive_aquire(struct burn_drive_info *drive_infos[],
|
||||
if(ret<=0)
|
||||
goto ex;
|
||||
drive_grabbed= 1;
|
||||
ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive, !!(flag&2));
|
||||
ret= isoburn_welcome_media(&o, (*drive_infos)[0].drive,
|
||||
(flag&8) | !!(flag&2));
|
||||
if(ret<=0)
|
||||
goto ex;
|
||||
|
||||
@ -925,31 +956,24 @@ int isoburn_report_iso_error(int iso_error_code, char msg_text[], int os_errno,
|
||||
}
|
||||
|
||||
|
||||
/* API
|
||||
@param flag bit0-7: info return mode
|
||||
0= do not return anything in info (do not even touch it)
|
||||
1= return volume id
|
||||
/* @param flag bit0-7: info return mode
|
||||
0= do not return anything in info (do not even touch it)
|
||||
1= return volume id
|
||||
bit14= -reserved -
|
||||
bit15= -reserved-
|
||||
@return 1 seems to be a valid ISO image , 0 format not recognized, <0 error
|
||||
*/
|
||||
int isoburn_read_iso_head(struct burn_drive *d, int lba,
|
||||
int *image_blocks, char *info, int flag)
|
||||
int isoburn_read_iso_head_parse(struct burn_drive *d, unsigned char *data,
|
||||
int *image_blocks, char *info, int flag)
|
||||
{
|
||||
unsigned char buffer[64*1024], *data;
|
||||
int ret, i, info_mode;
|
||||
off_t data_count;
|
||||
int i, info_mode;
|
||||
|
||||
*image_blocks= 0;
|
||||
ret = burn_read_data(d, ((off_t) lba) * (off_t) 2048, (char *) buffer,
|
||||
(off_t) 64*1024, &data_count, 2); /* no error messages */
|
||||
if(ret<=0)
|
||||
return(0);
|
||||
|
||||
data= buffer+32*1024;
|
||||
/* is this an ISO image ? */
|
||||
if(data[0]!=1)
|
||||
return(0);
|
||||
if(strncmp((char *) (data+1),"CD001",5)!=0)
|
||||
return(0);
|
||||
/* believe so */
|
||||
|
||||
*image_blocks= data[80] | (data[81]<<8) | (data[82]<<16) | (data[83]<<24);
|
||||
info_mode= flag&255;
|
||||
@ -971,11 +995,53 @@ int isoburn_read_iso_head(struct burn_drive *d, int lba,
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* API
|
||||
@param flag bit0-7: info return mode
|
||||
0= do not return anything in info (do not even touch it)
|
||||
1= return volume id
|
||||
bit14= check both half buffers (not only second)
|
||||
return 2 if found in first block
|
||||
bit15= return-1 on read error
|
||||
@return 1 seems to be a valid ISO image , 2 found in first half buffer,
|
||||
0 format not recognized, <0 error
|
||||
*/
|
||||
int isoburn_read_iso_head(struct burn_drive *d, int lba,
|
||||
int *image_blocks, char *info, int flag)
|
||||
{
|
||||
unsigned char buffer[64*1024];
|
||||
int ret;
|
||||
off_t data_count;
|
||||
|
||||
*image_blocks= 0;
|
||||
ret = burn_read_data(d, ((off_t) lba) * (off_t) 2048, (char *) buffer,
|
||||
(off_t) 64*1024, &data_count, 2); /* no error messages */
|
||||
if(ret<=0)
|
||||
return(-1*!!(flag&(1<<15)));
|
||||
|
||||
if(flag&(1<<14)) {
|
||||
ret= isoburn_read_iso_head_parse(d, buffer, image_blocks, info,
|
||||
flag&255);
|
||||
if(ret<0)
|
||||
return(ret);
|
||||
if(ret>0)
|
||||
return(2);
|
||||
}
|
||||
ret= isoburn_read_iso_head_parse(d, buffer+32*1024, image_blocks, info,
|
||||
flag&255);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= allow unemulated media
|
||||
bit1= free scanning without enclosing LBA-0-header
|
||||
@return -1 severe error, 0= no neat header chain, 1= credible chain read
|
||||
*/
|
||||
int isoburn_emulate_toc(struct burn_drive *d, int flag)
|
||||
{
|
||||
int ret, image_size= 0, lba, track_blocks, session_count= 0;
|
||||
int ret, image_size= 0, lba, track_blocks, session_count= 0, read_flag= 0;
|
||||
int scan_start= 0;
|
||||
struct isoburn *o;
|
||||
struct isoburn_toc_entry *item;
|
||||
char msg[160];
|
||||
@ -986,20 +1052,32 @@ int isoburn_emulate_toc(struct burn_drive *d, int flag)
|
||||
return(-1);
|
||||
if(o==NULL)
|
||||
return(-1);
|
||||
if(o->emulation_mode<=0)
|
||||
if(o->emulation_mode<=0 && !(flag&1))
|
||||
return(0);
|
||||
|
||||
lba= 0;
|
||||
ret= isoburn_read_iso_head(d, lba, &image_size, NULL, 0);
|
||||
if(ret<=0)
|
||||
{ret= 0; goto failure;}
|
||||
|
||||
lba= Libisoburn_overwriteable_starT;
|
||||
while(lba<image_size) {
|
||||
|
||||
ret= isoburn_read_iso_head(d, lba, &track_blocks, NULL, 0);
|
||||
if(!(flag&2)) {
|
||||
ret= isoburn_read_iso_head(d, lba, &image_size, NULL, 0);
|
||||
if(ret<=0)
|
||||
{ret= 0; goto failure;}
|
||||
lba= Libisoburn_overwriteable_starT;
|
||||
}
|
||||
while(lba<image_size || (flag&2)) {
|
||||
read_flag= 0;
|
||||
if(flag&2)
|
||||
read_flag= (1<<15)|((session_count>0)<<14);
|
||||
ret= isoburn_read_iso_head(d, lba, &track_blocks, NULL, read_flag);
|
||||
if(ret<=0) {
|
||||
if(session_count>0) {
|
||||
if(flag&2) {
|
||||
if(ret==0) {
|
||||
/* try at next 64 k block (check both 32 k halves) */
|
||||
lba+= 32;
|
||||
if(lba-scan_start <= Libisoburn_toc_scan_max_gaP)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sprintf(msg,
|
||||
"Chain of ISO session headers broken at #%d, LBA %ds",
|
||||
session_count+1, lba);
|
||||
@ -1007,6 +1085,8 @@ int isoburn_emulate_toc(struct burn_drive *d, int flag)
|
||||
}
|
||||
{ret= 0; goto failure;}
|
||||
}
|
||||
if(ret==2) /* ISO header was found in first half block */
|
||||
lba-= 16;
|
||||
ret= isoburn_toc_entry_new(&item, o->toc, 0);
|
||||
if(ret<=0) {
|
||||
burn_msgs_submit(0x00060000,
|
||||
@ -1025,6 +1105,7 @@ int isoburn_emulate_toc(struct burn_drive *d, int flag)
|
||||
lba+= track_blocks;
|
||||
if(lba % Libisoburn_nwa_alignemenT)
|
||||
lba+= Libisoburn_nwa_alignemenT - (lba % Libisoburn_nwa_alignemenT);
|
||||
scan_start= lba;
|
||||
}
|
||||
sprintf(msg,
|
||||
"Chain of ISO session headers yielded %d sessions", session_count);
|
||||
@ -1110,7 +1191,7 @@ struct isoburn_toc_disc *isoburn_toc_drive_get_disc(struct burn_drive *d)
|
||||
|
||||
/* is the media emulated multi-session ? */
|
||||
ret= isoburn_find_emulator(&o, d, 0);
|
||||
if(ret<=0)
|
||||
if(ret<0)
|
||||
goto libburn;
|
||||
if(o->toc==NULL)
|
||||
goto libburn;
|
||||
|
@ -351,6 +351,19 @@ struct isoburn_imgen_opts {
|
||||
*/
|
||||
#define Libisoburn_nwa_alignemenT 32
|
||||
|
||||
|
||||
/* Alignment for outer session scanning with -ROM drives.
|
||||
(E.g. my DVD-ROM drive shows any DVD type as 0x10 "DVD-ROM" with
|
||||
more or less false capacity and TOC.)
|
||||
*/
|
||||
#define Libisoburn_toc_scan_alignemenT 16
|
||||
|
||||
/* Maximum gap to be bridged during a outer TOC scan. Gaps appear between the
|
||||
end of a session and the start of the next session.
|
||||
*/
|
||||
#define Libisoburn_toc_scan_max_gaP 8192
|
||||
|
||||
|
||||
/* Size of target_iso_head which is to be written during
|
||||
isoburn_activate_session()
|
||||
*/
|
||||
|
@ -330,6 +330,10 @@ int isoburn_drive_scan_and_grab(struct burn_drive_info *drive_infos[],
|
||||
bit1= regard overwriteable media as blank
|
||||
bit2= if the drive is a regular disk file: truncate it to
|
||||
the write start address
|
||||
bit3= if the drive reports a read-only profile try to read
|
||||
table of content by scanning for ISO image headers.
|
||||
(depending on media type and drive this might
|
||||
help or it might make the resulting toc even worse)
|
||||
@return 1 = success , 0 = drive not found , <0 = other error
|
||||
*/
|
||||
int isoburn_drive_aquire(struct burn_drive_info *drive_infos[],
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2008.05.07.214442"
|
||||
#define Xorriso_timestamP "2008.05.08.141054"
|
||||
|
Loading…
Reference in New Issue
Block a user