Let -truncate "sbsector" "new" work even if LBA-0-superblock is damaged

This commit is contained in:
2023-02-24 17:28:41 +01:00
parent 6a921c7411
commit b837ff30fc
5 changed files with 132 additions and 77 deletions

View File

@ -3028,6 +3028,7 @@ int Xorriso_overwrite_iso_head(struct XorrisO *xorriso,
/* @param flag bit0= insist on tag_type 4 (relocated superblock tag)
bit1= accept tag with ISO_MD5_AREA_CORRUPTED
*/
int Xorriso_find_sb_checksum(struct XorrisO *xorriso,
char *head_buffer, int *vd_end, int flag)
@ -3049,8 +3050,9 @@ int Xorriso_find_sb_checksum(struct XorrisO *xorriso,
i++;
ret= iso_util_decode_md5_tag(head_buffer + i * 2048, &tag_type, &pos,
&range_start, &range_size, &next_tag, md5, 0);
if(ret <= 0)
return(ret);
if(((unsigned int) ret) != ISO_MD5_AREA_CORRUPTED || !(flag & 2))
if(ret <= 0)
return(ret);
if((flag & 1) && tag_type != 4)
return(0); /* No other tag type is supposed to occur before type 4 */
}
@ -3158,6 +3160,8 @@ md5_comp_failed:;
bit2= issue message about success
bit3= check whether source blocks are banned by in_sector_map
bit4= refresh relocated sb checksum tag
bit5= bit1 for Xorriso_find_sb_checksum:
accept tag with ISO_MD5_AREA_CORRUPTED
*/
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
char *head_buffer, struct CheckmediajoB *job,
@ -3255,7 +3259,8 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
if(flag & 16) {
/* Find relocated sb checksum tag */
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 1);
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end,
1 | ((flag >> 4) & 2));
if(ret > 0) {
/* If it is recognizable then it matched in Xorriso_adjust_relocated_sb */
checksum_block= ret - 1;
@ -3271,7 +3276,7 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
Write only up to PVD end plus eventual invalidated tag.
*/
to_write= 2048 * 32;
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &i, 0);
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &i, ((flag >> 4) & 2));
if(ret > 0) {
if(!(flag & 16)) /* invalidate */
memset(head_buffer + (ret - 1) * 2048, 0, 8);
@ -3625,9 +3630,9 @@ int Xorriso_truncate_overwritable(struct XorrisO *xorriso, char *adr_mode,
{
int ret, iso_lba= 0, iso_session, iso_track, iso_size= 0, image_start_mode= 0;
int old_size, new_size, blocks, was_indev= 0, checksum_block= 0, vd_end;
int readable_blocks;
int readable_blocks, headless_mode= 0, i;
char image_start_value[81], *head_buffer= NULL, iso_volid[33];
char *sb_buffer= NULL;
char *sb_buffer= NULL, *checksum_pt;
struct burn_drive_info *dinfo;
struct burn_drive *drive = NULL, *in_drive = NULL;
struct burn_multi_caps *caps= NULL;
@ -3671,36 +3676,54 @@ int Xorriso_truncate_overwritable(struct XorrisO *xorriso, char *adr_mode,
if(ret <= 0) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Cannot read ISO 9660 Volume Descriptor from LBA 0");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
if((strcmp(adr_mode, "lba") == 0 || strcmp(adr_mode, "sbsector") == 0)
&& strcmp(adjust, "new") == 0) {
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
ret= burn_get_read_capacity(drive, &old_size, 0);
if(ret <= 0)
goto ex;
headless_mode= 1;
} else {
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
}
/* Check for PVD at image_start_value and learn new size */
ret= Xorriso_decode_load_adr(xorriso, "-truncate_overwritable",
adr_mode, adr_value, &image_start_mode,
image_start_value, 0);
if(ret <= 0)
goto ex;
ret= isoburn_get_mount_params(drive, image_start_mode, image_start_value,
&iso_lba, &iso_track, &iso_session, iso_volid,
0);
if(ret <= 0)
goto ex;
if(ret != 1) {
sprintf(xorriso->info_text,
if(headless_mode) {
iso_lba= Scanf_io_size(adr_value, 0);
ret= isoburn_read_iso_head(drive, iso_lba, &new_size, head_buffer,
2 | (1 << 12));
if(ret <= 0)
goto not_iso_9660;
} else {
/* Check for PVD at image_start_value and learn new size */
ret= Xorriso_decode_load_adr(xorriso, "-truncate_overwritable",
adr_mode, adr_value, &image_start_mode,
image_start_value, 0);
if(ret <= 0)
goto ex;
ret= isoburn_get_mount_params(drive, image_start_mode, image_start_value,
&iso_lba, &iso_track, &iso_session, iso_volid,
0);
if(ret <= 0)
goto ex;
if(ret != 1) {
not_iso_9660:;
sprintf(xorriso->info_text,
"-truncate_overwritable: Given address does not lead to ISO 9660 Volume Descriptor");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(iso_lba >= old_size) {
sprintf(xorriso->info_text,
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(iso_lba >= old_size) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Given address is larger than current ISO size");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= isoburn_read_iso_head(drive, iso_lba, &new_size, head_buffer, 2);
if(ret <= 0)
goto ex;
}
ret= isoburn_read_iso_head(drive, iso_lba, &new_size, head_buffer, 2);
if(ret <= 0)
goto ex;
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 0);
if(ret > 0)
@ -3760,13 +3783,33 @@ wrong_adjust:;
}
/* Load first 64 kB and transfer VDs from head_buffer */
ret= Xorriso_adjust_relocated_sb(xorriso, drive, head_buffer, &sb_buffer, 0);
if(ret <= 0)
goto ex;
if(headless_mode) {
Xorriso_alloc_meM(sb_buffer, char, 32 * 2048);
memcpy(sb_buffer, head_buffer, 32 * 2048);
for(i= 17; i < 32; i++)
if(strncmp(sb_buffer + i * 2048, "libisofs_sb_checksum_tag_v1", 27) == 0)
break;
if(i < 32) {
/* Convert superblock tag to provisory relocated superblock tag */
checksum_pt= sb_buffer + i * 2048;
memset(checksum_pt, 0, 2048);
sprintf(checksum_pt,
"libisofs_rlsb32_checksum_tag_v1 pos=%d range_start=0 range_size=%d",
i, i);
sprintf(checksum_pt + strlen(checksum_pt),
" session_start=%d md5=0123456789abcdef0123456789abcdef self=0123456789abcdef0123456789abcdef",
iso_lba);
}
} else {
ret= Xorriso_adjust_relocated_sb(xorriso, drive, head_buffer, &sb_buffer,
0);
if(ret <= 0)
goto ex;
}
/* Patch the size and write back */
ret= Xorriso_update_iso_lba0(xorriso, iso_lba, iso_size, sb_buffer,
NULL, 2 | 16);
NULL, 2 | 16 | ((!!headless_mode) << 5));
if(ret <= 0)
goto ex;