New command -truncate_overwritable

This commit is contained in:
2020-08-06 17:39:47 +02:00
parent ec49c627f9
commit 04a82ce28d
10 changed files with 885 additions and 98 deletions

View File

@ -2,7 +2,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2017 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -2866,24 +2866,169 @@ ex:
}
int Xorriso_overwrite_iso_head(struct XorrisO *xorriso,
struct burn_drive *drive, char *head_buffer,
int lba, int flag)
{
int ret;
off_t to_write;
to_write= 64 * 1024;
burn_drive_reset_simulate(drive, xorriso->do_dummy);
ret= burn_random_access_write(drive, (off_t) lba * (off_t) 2048,
head_buffer, to_write, 1);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
sprintf(xorriso->info_text,
"Cannot write new ISO image head to LBA %d", lba);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
return(1);
}
/* @param flag bit0= insist on tag_type 4 (relocated superblock tag)
*/
int Xorriso_find_sb_checksum(struct XorrisO *xorriso,
char *head_buffer, int *vd_end, int flag)
{
int i, tag_type, ret;
uint32_t pos, range_start, range_size, next_tag;
char md5[16];
*vd_end= 0;
/* Look for volume descriptor end */
for(i= 16; i < 32; i++)
if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0)
break;
/* Check whether the next one is a libisofs checksum tag */
if(i < 32) {
*vd_end= i;
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((flag & 1) && tag_type != 4)
return(0); /* No other tag type is supposed to occur before type 4 */
}
return(i + 1);
}
/* @param field_head Example: " md5="
*/
int Xorriso__set_iso_check_tag_md5(char *tag_data, char *field_head,
void **ctx, int *field_end, int flag)
{
char md5_bin[16], m32, *cpt;
int i;
iso_md5_end(ctx, md5_bin);
cpt= strstr(tag_data, field_head);
if(cpt == NULL)
return(0);
cpt+= strlen(field_head);
m32= cpt[32];
for(i= 0; i < 16; i++)
sprintf(cpt + 2 * i, "%2.2x", ((unsigned char *) md5_bin)[i]);
cpt[32]= m32;
*field_end= (cpt - tag_data) + 32;
return(1);
}
int Xorriso_verify_sb_tag(struct XorrisO *xorriso, char *head_buffer,
int checksum_block, int flag)
{
int tag_type, ret;
uint32_t pos, range_start, range_size, next_tag;
char md5_rec[16], md5_comp[16];
void *ctx= NULL;
/* Obtain checksum */
iso_util_decode_md5_tag(head_buffer + checksum_block * 2048,
&tag_type, &pos, &range_start, &range_size,
&next_tag, md5_rec, 0);
/* Verify checksum */
ret= iso_md5_start(&ctx);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(0);
}
ret= iso_md5_compute(ctx, head_buffer, checksum_block * 2048);
iso_md5_end(&ctx, md5_comp);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
return(0);
}
if(iso_md5_match(md5_rec, md5_comp))
return(1);
Xorriso_msgs_submit(xorriso, 0,
"Superblock data do not match superblock checksum tag",
0, "WARNING", 0);
return(0);
}
int Xorriso_refresh_sb_tag(struct XorrisO *xorriso, char *head_buffer,
int checksum_block, int flag)
{
int ret, field_end;
char md5_bin[16];
void *ctx= NULL;
/* Recompute checksum and update found checksum tag */;
ret= iso_md5_start(&ctx);
if(ret <= 0) {
no_md5_ctx:;
Xorriso_process_msg_queues(xorriso,0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(0);
}
ret= iso_md5_compute(ctx, head_buffer, checksum_block * 2048);
if(ret <= 0) {
md5_comp_failed:;
iso_md5_end(&ctx, md5_bin);
return(0);
}
Xorriso__set_iso_check_tag_md5(head_buffer + checksum_block * 2048,
" md5=", &ctx, &field_end, 0);
if(ret <= 0)
return(2);
ret= iso_md5_start(&ctx);
if(ret <= 0)
goto no_md5_ctx;
ret= iso_md5_compute(ctx, head_buffer + checksum_block * 2048,
field_end);
if(ret <= 0)
goto md5_comp_failed;
Xorriso__set_iso_check_tag_md5(head_buffer + checksum_block * 2048,
" self=", &ctx, &field_end, 0);
return(1);
}
/*
@param flag bit0= obtain iso_lba from indev
bit1= head_buffer already contains a valid head
bit2= issue message about success
bit3= check whether source blocks are banned by in_sector_map
bit4= refresh relocated sb checksum tag
*/
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
char *head_buffer, struct CheckmediajoB *job,
int flag)
{
int ret, full_size, i;
int ret, full_size, i, checksum_block= -1, vd_end;
char *headpt;
struct burn_drive_info *dinfo;
struct burn_drive *drive = NULL;
off_t seek_ret, to_write;
int tag_type;
uint32_t pos, range_start, range_size, next_tag;
char md5[16];
ret= Xorriso_may_burn(xorriso, 0);
if(ret <= 0)
@ -2960,33 +3105,41 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
}
}
}
/* patch ISO header */
full_size= iso_lba + isosize;
headpt= head_buffer + 32*1024;
for(i=0;i<4;i++)
headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
/* >>> What about Joliet et.al. ? */;
if(flag & 16) {
/* Find relocated sb checksum tag */
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 1);
if(ret > 0) {
/* If it is recognizable then it matched in Xorriso_adjust_relocated_sb */
checksum_block= ret - 1;
ret= Xorriso_refresh_sb_tag(xorriso, head_buffer, checksum_block, 0);
if(ret <= 0)
return(0);
}
}
if(job != NULL) {
/* This is a check_media superblock relocation:
Invalidate eventual libisofs checksum tags.
Write only up to PVD end plus eventual invalidated tag.
*/
/* Look for volume descriptor end */
for(i= 16; i < 32; i++)
if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0)
break;
/* Check whether the next one is a libisofs checksum tag */
if(i < 32) {
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) /* corrupted or not: invalidate */
memset(head_buffer + i * 2048, 0, 8);
to_write= 2048 * 32;
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &i, 0);
if(ret > 0) {
if(!(flag & 16)) /* invalidate */
memset(head_buffer + (ret - 1) * 2048, 0, 8);
to_write= 2048 * ret;
} else if(i > 0) {
to_write= 2048 * (i + 1);
}
to_write= 2048 * (i + 1);
seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
if(seek_ret == -1)
ret= 0;
@ -3001,16 +3154,9 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
}
} else {
/* This is a regular superblock relocation. Write full 64 kB. */
to_write= 64 * 1024;
burn_drive_reset_simulate(drive, xorriso->do_dummy);
ret= burn_random_access_write(drive, (off_t) 0, head_buffer, to_write, 1);
if(ret<=0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"Cannot write new ISO image head to LBA 0");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, 0, 0);
if(ret <= 0)
return(ret);
}
if(flag & 4) {
sprintf(xorriso->info_text,
@ -3021,6 +3167,485 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
}
/* @return 1= ok, 0= no match, -1= MD5 computation error,
-2= MD5 clone or start error
*/
int Xorriso_migrate_checksum_tag(struct XorrisO *xorriso, char *buffer,
int buf_base, int start,
int checksum_block, char md5_rec[16],
void *ctx_unch, void *ctx_chng, int flag)
{
int ret, to_compute;
char *headpt, md5_clone[16];
void *ctx_clone= NULL;
int field_end;
/* Checksum both up to before checksum tag */
headpt= buffer + start * 2048;
to_compute= (checksum_block - start) * 2048;
if(to_compute > 0) {
ret= iso_md5_compute(ctx_unch, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
ret= iso_md5_compute(ctx_chng, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
}
/* Verify with unchanged checksum */
ret= iso_md5_clone(ctx_unch, &ctx_clone);
if(ret <= 0)
{ret= -2; goto ex;}
iso_md5_end(&ctx_clone, md5_clone);
if(!iso_md5_match(md5_rec, md5_clone))
{ret= 0; goto ex;}
/* Compute unchanged rest of block range */
headpt= buffer + checksum_block * 2048;
to_compute= 2048;
ret= iso_md5_compute(ctx_unch, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
/* Replace checksum in tag by changed checksum */
ret= iso_md5_clone(ctx_chng, &ctx_clone);
if(ret <= 0)
{ret= -2; goto ex;}
Xorriso__set_iso_check_tag_md5(headpt, " md5=", &ctx_clone, &field_end, 0);
/* Recompute and write self= checksum */
ret= iso_md5_start(&ctx_clone);
if(ret <= 0)
{ret= -2; goto ex;}
ret= iso_md5_compute(ctx_clone, headpt, field_end);
if(ret <= 0)
{ret= -1; goto ex;}
Xorriso__set_iso_check_tag_md5(headpt, " self=", &ctx_clone, &field_end, 0);
/* Add rest of head_buffer to changed checksum */
ret= iso_md5_compute(ctx_chng, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
ret= 1;
ex:;
if(ctx_clone != NULL)
iso_md5_end(&ctx_clone, md5_clone);
return(ret);
}
/* Verify and re-compute tree and session checksum tag */
int Xorriso_refresh_ts_tags(struct XorrisO *xorriso,
struct burn_drive *drive,
void *ctx_unch, void *ctx_chng,
int iso_lba, int session_size,
int checksum_block, int flag)
{
int i, ret, tag_type, look_for_tag, check_start, look_from_block, was_change;
off_t read_pos, to_read, data_count;
uint32_t pos, range_start, range_size, next_tag;
char md5_rec[16];
char *buf= NULL;
look_for_tag= 3; /* tree tag */
look_from_block= checksum_block + 1; /* first buffer is already partly done */
Xorriso_alloc_meM(buf, char, 32 * 2048);
for(read_pos= iso_lba; read_pos < iso_lba + session_size; read_pos+= 32) {
was_change= 0;
to_read= 32;
if(read_pos + to_read > iso_lba + session_size)
to_read= iso_lba + session_size - read_pos;
ret= burn_read_data(drive, read_pos * (off_t) 2048, buf,
to_read * (off_t) 2048, &data_count, 0);
if(ret <= 0)
{ret= 0; goto ex;}
check_start= look_from_block;
for(i= look_from_block; i < to_read; i++) {
/* Watch out for tag */
ret= iso_util_decode_md5_tag(buf + i * 2048,
&tag_type, &pos, &range_start, &range_size,
&next_tag, md5_rec, look_for_tag);
if(ret < 0 ) {
ret= 0; goto ex;
} else if(ret == 1) {
if(tag_type != look_for_tag) {
sprintf(xorriso->info_text,
"Encountered checksum tag type %d while looking for %d",
tag_type, look_for_tag);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
ret= 2; goto ex;
}
/* Checksum up to before tag, verify,
if match replace checksum and write */
ret= Xorriso_migrate_checksum_tag(xorriso, buf, read_pos, check_start,
i, md5_rec, ctx_unch, ctx_chng, 0);
if(ret == -2)
goto ex;
if(ret < 0)
{ret= 0; goto ex;}
if(ret == 0) {
sprintf(xorriso->info_text,
"Checksum tag MD5 mismatch in old session state");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
ret= 2; goto ex;
}
was_change= 1;
if(look_for_tag == 3) {
look_for_tag= 1; /* session tag */
} else {
look_for_tag= -1;
break;
}
check_start= i + 1;
}
}
look_from_block= 0; /* all following buffer need processing from start */
if(was_change) {
ret= burn_random_access_write(drive, (off_t) read_pos * (off_t) 2048,
buf, to_read * (off_t) 2048, 1);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
sprintf(xorriso->info_text,
"Cannot write new checksum tag data to LBA %d", (int) read_pos);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
if(look_for_tag < 0)
{ret= 1; goto ex;}
/* Checksum what was not checksummed yet */
if(to_read - check_start > 0) {
ret= iso_md5_compute(ctx_unch, buf + 2048 * check_start,
(to_read - check_start) * 2048);
if(ret <= 0)
{ret= 0; goto ex;}
ret= iso_md5_compute(ctx_chng, buf + 2048 * check_start,
(to_read - check_start) * 2048);
if(ret <= 0)
{ret= 0; goto ex;}
}
}
ret= 1;
ex:;
Xorriso_free_meM(buf);
return(ret);
}
int Xorriso_adjust_session_size(struct XorrisO *xorriso,
struct burn_drive *drive,
char *head_buffer,
int iso_lba, int iso_size,
int checksum_block, int session_size, int flag)
{
int i, ret, tag_type;
uint32_t pos, range_start, range_size, next_tag;
char *headpt, md5_unch[16], md5_chng[16], md5_clone[16], md5_rec[16];
void *ctx_unch= NULL, *ctx_chng= NULL, *ctx_clone= NULL;
if(checksum_block > 0) {
/* Obtain recorded superblock MD5 */
ret= iso_util_decode_md5_tag(head_buffer + checksum_block * 2048,
&tag_type, &pos, &range_start, &range_size,
&next_tag, md5_rec, 0);
if(ret <= 0 || tag_type != 2) {
sprintf(xorriso->info_text,
"Encountered checksum tag type %d while looking for 2", tag_type);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
checksum_block= 0;
}
}
if(checksum_block > 0) {
/* Create md5 context for unchanged state */
ret= iso_md5_start(&ctx_unch);
if(ret <= 0) {
no_ctx:;
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
goto ex;
}
/* Checksum up to before PVD */
ret= iso_md5_compute(ctx_unch, head_buffer, 32768);
if(ret <= 0)
goto ex;
/* Before the first change: obtain md5 object for changed state */
ret= iso_md5_clone(ctx_unch, &ctx_chng);
if(ret <= 0)
goto no_ctx;
/* Add PVD to unchanged checksum */
ret= iso_md5_compute(ctx_unch, head_buffer + 32768, 2048);
if(ret <= 0)
goto ex;
}
/* Update session PVD at iso_lba+16 to iso_size */
headpt= head_buffer + 32 * 1024;
for(i= 0; i < 4; i++)
headpt[87 - i]= headpt[80 + i]= (iso_size >> (8 * i)) & 0xff;
if(checksum_block > 0) {
/* Add changed PVD to changed checksum */
ret= iso_md5_compute(ctx_chng, head_buffer + 32768, 2048);
if(ret <= 0)
goto ex;
ret= Xorriso_migrate_checksum_tag(xorriso, head_buffer, iso_lba, 17,
checksum_block, md5_rec,
ctx_unch, ctx_chng, 0);
if(ret == -2)
goto no_ctx;
if(ret < 0)
{ret= 0; goto ex;}
if(ret == 0) {
sprintf(xorriso->info_text,
"Superblock MD5 mismatch in old session state");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
checksum_block= 0;
}
}
ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, iso_lba, 0);
if(ret <= 0)
goto ex;
if(checksum_block > 0) {
/* Verify and re-compute existing checksum tree and session tag */
ret= Xorriso_refresh_ts_tags(xorriso, drive, ctx_unch, ctx_chng,
iso_lba, session_size, checksum_block, 0);
if(ret == -2)
goto no_ctx;
if(ret <= 0)
goto ex;
}
ret= 1;
ex:;
Xorriso_process_msg_queues(xorriso, 0);
if(ctx_unch != NULL)
iso_md5_end(&ctx_unch, md5_unch);
if(ctx_chng != NULL)
iso_md5_end(&ctx_chng, md5_chng);
if(ctx_clone != NULL)
iso_md5_end(&ctx_clone, md5_clone);
return(ret);
}
/* Read relocated superblock and patch in the VDs of the session superblock */
int Xorriso_adjust_relocated_sb(struct XorrisO *xorriso,
struct burn_drive *drive,
char *head_buffer,
char **sb_buffer,
int flag)
{
int ret, old_size, i, vd_end, checksum_block= -1;
char *buffer, *checksum= NULL;
*sb_buffer= NULL;
Xorriso_alloc_meM(*sb_buffer, char, 32 * 2048);
buffer= *sb_buffer;
Xorriso_alloc_meM(checksum, char, 2048);
ret= isoburn_read_iso_head(drive, 0, &old_size, buffer, 2);
if(ret <= 0)
goto ex;
ret= Xorriso_find_sb_checksum(xorriso, buffer, &vd_end, 0);
if(ret <= 0)
goto ex;
if(ret > 0) {
checksum_block= ret - 1;
memcpy(checksum, buffer + checksum_block * 2048, 2048);
ret= Xorriso_verify_sb_tag(xorriso, buffer, checksum_block, 0);
if(ret <= 0) {
checksum_block= -1;
memset(checksum, 0, 8);
}
}
for(i= 16; i < 32; i++) {
memcpy(buffer + i * 2048, head_buffer + i * 2048, 2048);
if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0) {
i++;
break;
}
}
if(checksum_block >= 0 && i < 32)
memcpy(buffer + i * 2048, checksum, 2048);
ret= 1;
ex:
if(ret <= 0)
Xorriso_free_meM(*sb_buffer);
Xorriso_free_meM(checksum);
return(ret);
}
int Xorriso_truncate_overwritable(struct XorrisO *xorriso, char *adr_mode,
char *adr_value, char *adjust, int flag)
{
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;
char image_start_value[81], *head_buffer= NULL, iso_volid[33];
char *sb_buffer= NULL;
struct burn_drive_info *dinfo;
struct burn_drive *drive = NULL, *in_drive = NULL;
struct burn_multi_caps *caps= NULL;
Xorriso_alloc_meM(head_buffer, char, 32 * 2048);
if(Xorriso_change_is_pending(xorriso, 0)) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Image changes pending. -commit or -rollback first");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= Xorriso_may_burn(xorriso, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to activate an older session", 2);
if(ret <= 0)
goto ex;
/* Is it 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) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Loaded medium is not random-access overwritable");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
ret= Xorriso_reassure(xorriso, "-truncate_overwritable",
"activates an older session and destroys newer ones", 0);
if(ret <= 0)
{ret= 2; goto ex;}
/* Learn old size */
ret= isoburn_read_iso_head(drive, 0, &old_size, iso_volid, 0);
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;
}
/* 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,
"-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,
"-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;
}
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)
checksum_block= ret - 1;
/* Default is "new" */
iso_size= new_size;
if(strcmp(adjust, "old") == 0) {
/* ISO size before truncation */
iso_size= old_size - iso_lba;
} else if(adjust[0] == '+') {
/* Add-on size to new */
blocks= Scanf_io_size(adjust + 1, 0) / 2048;
if(blocks < 0)
goto wrong_adjust;
iso_size+= blocks;
} else if(adjust[0] >= '0' && adjust[0] <= '9') {
/* Add-on size to new */
blocks= Scanf_io_size(adjust, 0) / 2048;
if(blocks < iso_lba + iso_size) {
wrong_adjust:;
sprintf(xorriso->info_text,
"-truncate_overwritable: Given total filesystem size is smaller than new session size");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
iso_size= blocks - iso_lba;
}
ret= burn_get_read_capacity(drive, &readable_blocks, 0);
Xorriso_process_msg_queues(xorriso, 0);
if(ret > 0) {
if(iso_lba + iso_size > readable_blocks) {
sprintf(xorriso->info_text, "-truncate_overwritable: Given total filesystem size is larger than formatted medium size");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
/* Give up possible input drive */
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &in_drive, "", 16);
if(ret < 0)
goto ex;
if(ret == 1) {
ret= Xorriso_give_up_drive(xorriso, 1);
if(ret<=0)
goto ex;
was_indev= 1;
}
if(iso_size != new_size) {
ret=Xorriso_adjust_session_size(xorriso, drive, head_buffer,
iso_lba, iso_size, checksum_block,
new_size, 0);
if(ret <= 0)
goto ex;
}
/* 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;
/* Patch the size and write back */
ret= Xorriso_update_iso_lba0(xorriso, iso_lba, iso_size, sb_buffer,
NULL, 2 | 16);
if(ret <= 0)
goto ex;
ret= Xorriso_reaquire_outdev(xorriso, 2 + was_indev);
if(ret <= 0)
goto ex;
ret= 1;
ex:
if(caps!=NULL)
burn_disc_free_multi_caps(&caps);
Xorriso_free_meM(head_buffer);
Xorriso_free_meM(sb_buffer);
Xorriso_process_msg_queues(xorriso,0);
return(ret);
}
int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag)
{
int ret;