|
|
|
|
|
|
|
|
|
|
|
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
|
|
|
|
|
|
|
|
Copyright 2007-2011 Thomas Schmitt, <scdbackup@gmx.net>
|
|
|
|
|
|
|
|
Provided under GPL version 2 or later.
|
|
|
|
|
|
|
|
This file contains functions which are needed to write sessions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "../config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#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>
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_STDINT_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#else
|
|
|
|
#ifdef HAVE_INTTYPES_H
|
|
|
|
#include <inttypes.h>
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef Xorriso_standalonE
|
|
|
|
|
|
|
|
#ifdef Xorriso_with_libjtE
|
|
|
|
#include "../libjte/libjte.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#ifdef Xorriso_with_libjtE
|
|
|
|
#include <libjte/libjte.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* ! Xorriso_standalonE */
|
|
|
|
|
|
|
|
#include "xorriso.h"
|
|
|
|
#include "xorriso_private.h"
|
|
|
|
|
|
|
|
#include "lib_mgt.h"
|
|
|
|
#include "drive_mgt.h"
|
|
|
|
#include "iso_img.h"
|
|
|
|
#include "iso_tree.h"
|
|
|
|
#include "write_run.h"
|
|
|
|
|
|
|
|
|
|
|
|
int Xorriso_make_write_options(
|
|
|
|
struct XorrisO *xorriso, struct burn_drive *drive,
|
|
|
|
struct burn_write_opts **burn_options, int flag)
|
|
|
|
{
|
|
|
|
int drive_role, stream_mode= 0;
|
|
|
|
|
|
|
|
*burn_options= burn_write_opts_new(drive);
|
|
|
|
if(*burn_options==NULL) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
sprintf(xorriso->info_text,"Cannot allocate option set");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
burn_write_opts_set_simulate(*burn_options, !!xorriso->do_dummy);
|
|
|
|
drive_role= burn_drive_get_drive_role(drive);
|
|
|
|
burn_write_opts_set_multi(*burn_options,
|
|
|
|
!(xorriso->do_close || drive_role==0 || drive_role==3));
|
|
|
|
burn_drive_set_speed(drive, xorriso->speed, xorriso->speed);
|
|
|
|
if(xorriso->do_stream_recording == 1)
|
|
|
|
stream_mode= 1;
|
|
|
|
else if(xorriso->do_stream_recording == 2)
|
|
|
|
stream_mode= 51200; /* 100 MB */
|
|
|
|
else if(xorriso->do_stream_recording >= 16)
|
|
|
|
stream_mode= xorriso->do_stream_recording;
|
|
|
|
burn_write_opts_set_stream_recording(*burn_options, stream_mode);
|
|
|
|
|
|
|
|
#ifdef Xorriso_dvd_obs_default_64K
|
|
|
|
if(xorriso->dvd_obs == 0)
|
|
|
|
burn_write_opts_set_dvd_obs(*burn_options, 64 * 1024);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
burn_write_opts_set_dvd_obs(*burn_options, xorriso->dvd_obs);
|
|
|
|
|
|
|
|
burn_write_opts_set_stdio_fsync(*burn_options, xorriso->stdio_sync);
|
|
|
|
burn_write_opts_set_underrun_proof(*burn_options, 1);
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= do not write but only prepare and return size in sectors
|
|
|
|
bit1= do not use isoburn wrappers, do not assume libisofs
|
|
|
|
*/
|
|
|
|
int Xorriso_sanitize_image_size(struct XorrisO *xorriso,
|
|
|
|
struct burn_drive *drive, struct burn_disc *disc,
|
|
|
|
struct burn_write_opts *burn_options, int flag)
|
|
|
|
{
|
|
|
|
int ret, img_sectors, num_sessions= 0, num_tracks= 0, padding= 0, profile;
|
|
|
|
int media_space, lba, nwa, multi_emul_blocks= 0;
|
|
|
|
char profile_name[80];
|
|
|
|
struct burn_session **sessions;
|
|
|
|
struct burn_track **tracks;
|
|
|
|
enum burn_disc_status s;
|
|
|
|
|
|
|
|
img_sectors= burn_disc_get_sectors(disc);
|
|
|
|
|
|
|
|
sessions= burn_disc_get_sessions(disc, &num_sessions);
|
|
|
|
if(sessions==NULL || num_sessions < 1) {
|
|
|
|
no_track:;
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
sprintf(xorriso->info_text,"Program error : no track in prepared disc");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
}
|
|
|
|
tracks= burn_session_get_tracks(sessions[0], &num_tracks);
|
|
|
|
if(tracks==NULL || num_tracks < 1)
|
|
|
|
goto no_track;
|
|
|
|
|
|
|
|
padding= 0;
|
|
|
|
ret= burn_disc_get_profile(drive, &profile, profile_name);
|
|
|
|
padding= xorriso->padding / 2048;
|
|
|
|
if(xorriso->padding > padding * 2048)
|
|
|
|
padding++;
|
|
|
|
if(img_sectors>0 && ret>0 &&
|
|
|
|
(profile==0x09 || profile==0x0a)) { /* CD-R , CD-RW */
|
|
|
|
if(img_sectors + padding < Xorriso_cd_min_track_sizE) {
|
|
|
|
padding= Xorriso_cd_min_track_sizE - img_sectors;
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Expanded track to minimum size of %d sectors",
|
|
|
|
Xorriso_cd_min_track_sizE);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(xorriso->alignment == 0 && ! (xorriso->no_emul_toc & 1)) {
|
|
|
|
ret= isoburn_needs_emulation(drive);
|
|
|
|
if(ret > 0) {
|
|
|
|
/* Take care that the session is padded up to the future NWA.
|
|
|
|
Else with padding < 32 it could happen that PVDs from older
|
|
|
|
sessions survive and confuse -rom_toc_scan.
|
|
|
|
*/
|
|
|
|
xorriso->alignment= 32;
|
|
|
|
s= isoburn_disc_get_status(drive);
|
|
|
|
if(s == BURN_DISC_BLANK) {
|
|
|
|
/* Count blocks before nwa as part of the image */;
|
|
|
|
ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa);
|
|
|
|
if(ret <= 0)
|
|
|
|
nwa= 0;
|
|
|
|
multi_emul_blocks= nwa;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(flag & 2)) {
|
|
|
|
|
|
|
|
#ifdef Xorriso_with_libjtE
|
|
|
|
/* JTE : no multi-session, no_emul_toc, padding in libisofs */
|
|
|
|
if(xorriso->libjte_handle != NULL)
|
|
|
|
padding= 0;
|
|
|
|
#endif /* ! Xorriso_with_libjtE */
|
|
|
|
|
|
|
|
if(xorriso->do_padding_by_libisofs)
|
|
|
|
padding= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(xorriso->alignment > 0) {
|
|
|
|
if(img_sectors > 0) {
|
|
|
|
ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa);
|
|
|
|
if(ret <= 0)
|
|
|
|
nwa= 0;
|
|
|
|
lba= (nwa + img_sectors + padding) % xorriso->alignment;
|
|
|
|
if(lba > 0)
|
|
|
|
padding+= xorriso->alignment - lba;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1);
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
|
|
|
if(flag&2)
|
|
|
|
media_space= burn_disc_available_space(drive, burn_options) /
|
|
|
|
(off_t) 2048;
|
|
|
|
else
|
|
|
|
media_space= isoburn_disc_available_space(drive, burn_options) /
|
|
|
|
(off_t) 2048;
|
|
|
|
if(media_space < img_sectors + padding) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
sprintf(xorriso->info_text,"Image size %ds exceeds free space on media %ds",
|
|
|
|
img_sectors + padding, media_space);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
if(flag&1) {
|
|
|
|
ret= multi_emul_blocks + img_sectors + padding;
|
|
|
|
} else
|
|
|
|
ret= 1;
|
|
|
|
ex:;
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Xorriso_auto_format(struct XorrisO *xorriso, int flag)
|
|
|
|
{
|
|
|
|
int ret, profile, status, num_formats;
|
|
|
|
char profile_name[80];
|
|
|
|
struct burn_drive_info *dinfo;
|
|
|
|
struct burn_drive *drive;
|
|
|
|
off_t size;
|
|
|
|
unsigned dummy;
|
|
|
|
|
|
|
|
ret= Xorriso_may_burn(xorriso, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
|
|
|
|
"on attempt to autoformat", 2);
|
|
|
|
if(ret<=0)
|
|
|
|
return(0);
|
|
|
|
ret= burn_disc_get_profile(drive, &profile, profile_name);
|
|
|
|
if(ret>0 && (profile==0x12 || profile==0x43)) { /* DVD-RAM or BD-RE */
|
|
|
|
ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
|
|
|
|
if(ret>0 && status==BURN_FORMAT_IS_UNFORMATTED) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Unformatted %s media detected. Trying -format fast.",
|
|
|
|
profile_name);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
ret= Xorriso_format_media(xorriso, (off_t) 0, 1 | 4);
|
|
|
|
if(ret<=0) {
|
|
|
|
sprintf(xorriso->info_text, "Automatic formatting of %s failed",
|
|
|
|
profile_name);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive,
|
|
|
|
IsoImage *img, struct isoburn_imgen_opts *sopts,
|
|
|
|
int flag)
|
|
|
|
{
|
|
|
|
int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks;
|
|
|
|
char volid[33];
|
|
|
|
FILE *fp= NULL;
|
|
|
|
char *buf= NULL, *bufpt= NULL;
|
|
|
|
off_t hd_lba;
|
|
|
|
unsigned char *ub;
|
|
|
|
ElToritoBootImage *bootimg;
|
|
|
|
IsoFile *bootimg_node;
|
|
|
|
uint32_t offst;
|
|
|
|
enum burn_disc_status state;
|
|
|
|
|
|
|
|
Xorriso_alloc_meM(buf, char, 32768);
|
|
|
|
system_area_options= xorriso->system_area_options;
|
|
|
|
memset(buf, 0, 32768);
|
|
|
|
if(xorriso->system_area_disk_path[0] == 0) {
|
|
|
|
if(xorriso->patch_system_area) {
|
|
|
|
ret= iso_image_get_system_area(img, buf, &options, 0);
|
|
|
|
if(ret == 0) {
|
|
|
|
goto do_set;
|
|
|
|
} else if(ret < 0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when inquiring System Area data of ISO 9660 image",
|
|
|
|
0, "FAILURE", 1);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
} else {
|
|
|
|
system_area_options= xorriso->patch_system_area;
|
|
|
|
/* Check whether partition 1 ends at image end */;
|
|
|
|
ub= (unsigned char *) buf;
|
|
|
|
hd_lba= (ub[454] | (ub[455] << 8) | (ub[456] << 16) | (ub[457] << 24)) +
|
|
|
|
(ub[458] | (ub[459] << 8) | (ub[460] << 16) | (ub[461] << 24));
|
|
|
|
|
|
|
|
iso_lba= -1;
|
|
|
|
ret= isoburn_disc_get_msc1(drive, &start_lba);
|
|
|
|
if(ret > 0) {
|
|
|
|
ret= isoburn_read_iso_head(drive, start_lba, &image_blocks,
|
|
|
|
volid, 1);
|
|
|
|
if(ret > 0)
|
|
|
|
iso_lba= start_lba + image_blocks;
|
|
|
|
}
|
|
|
|
if(((off_t) iso_lba) * (off_t) 4 > hd_lba) {
|
|
|
|
system_area_options= 0;
|
|
|
|
} else if((xorriso->patch_system_area & 1) &&
|
|
|
|
((off_t) iso_lba) * (off_t) 4 != hd_lba) {
|
|
|
|
system_area_options= 0;
|
|
|
|
} else if((xorriso->patch_system_area & 2) &&
|
|
|
|
((off_t) iso_lba) * (off_t) 4 + (off_t) (63 * 256) < hd_lba) {
|
|
|
|
system_area_options= 0;
|
|
|
|
} else if(xorriso->patch_system_area & 2) { /* isohybrid patching */
|
|
|
|
/* Check whether bytes 432-345 point to ElTorito LBA */
|
|
|
|
hd_lba= ub[432] | (ub[433] << 8) | (ub[434] << 16) | (ub[435] << 24);
|
|
|
|
ret= iso_image_get_boot_image(img, &bootimg, &bootimg_node, NULL);
|
|
|
|
if(ret != 1)
|
|
|
|
system_area_options= 0;
|
|
|
|
else if(bootimg_node != NULL) {
|
|
|
|
Xorriso__file_start_lba((IsoNode *) bootimg_node, &(iso_lba), 0);
|
|
|
|
if(((off_t) iso_lba) * (off_t) 4 != hd_lba)
|
|
|
|
system_area_options= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(system_area_options == 0) {
|
|
|
|
Xorriso_msgs_submit(xorriso, 0,
|
|
|
|
"Loaded System Area data are not suitable for MBR patching.",
|
|
|
|
0, "DEBUG", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bufpt= buf;
|
|
|
|
ret= 1;
|
|
|
|
} else
|
|
|
|
ret= 0;
|
|
|
|
goto do_set;
|
|
|
|
}
|
|
|
|
if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0)
|
|
|
|
{ret= 1; goto do_set;}
|
|
|
|
|
|
|
|
ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path,
|
|
|
|
"rb", &fp, 2);
|
|
|
|
if(ret <= 0)
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
ret= fread(buf, 1, 32768, fp);
|
|
|
|
if(ret < 32768) {
|
|
|
|
if(ferror(fp)) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Error when reading -boot_image system_area=");
|
|
|
|
Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bufpt= buf;
|
|
|
|
|
|
|
|
do_set:;
|
|
|
|
if(ret > 0 && xorriso->system_area_disk_path[0]) {
|
|
|
|
sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ",
|
|
|
|
ret);
|
|
|
|
Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
}
|
|
|
|
ret= isoburn_igopt_set_system_area(sopts, bufpt, system_area_options);
|
|
|
|
if(ret != ISO_SUCCESS) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when attaching System Area data to ISO 9660 image",
|
|
|
|
0, "FAILURE", 1);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
offst= xorriso->partition_offset;
|
|
|
|
state= isoburn_disc_get_status(drive);
|
|
|
|
if(state == BURN_DISC_APPENDABLE) {
|
|
|
|
ret= isoburn_get_img_partition_offset(drive, &offst);
|
|
|
|
if(ret == 1) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Preserving in ISO image: -boot_image any partition_offset=%lu",
|
|
|
|
(unsigned long) offst);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
} else
|
|
|
|
offst= xorriso->partition_offset;
|
|
|
|
}
|
|
|
|
ret= isoburn_igopt_set_part_offset(sopts, offst,
|
|
|
|
xorriso->partition_secs_per_head,
|
|
|
|
xorriso->partition_heads_per_cyl);
|
|
|
|
if(ret != ISO_SUCCESS) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when setting partition offset", 0, "FAILURE", 1);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
ret= 1;
|
|
|
|
ex:;
|
|
|
|
if(fp != NULL && fp != stdin)
|
|
|
|
fclose(fp);
|
|
|
|
Xorriso_free_meM(buf);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= do not increment boot_count
|
|
|
|
and do not reset boot parameters
|
|
|
|
bit1= dispose attached boot images
|
|
|
|
*/
|
|
|
|
int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
char *cpt;
|
|
|
|
struct burn_drive_info *source_dinfo;
|
|
|
|
struct burn_drive *source_drive;
|
|
|
|
IsoImage *image= NULL;
|
|
|
|
IsoNode *node;
|
|
|
|
ElToritoBootImage *bootimg;
|
|
|
|
enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL;
|
|
|
|
char *bin_path;
|
|
|
|
int emul, platform_id;
|
|
|
|
off_t load_size;
|
|
|
|
struct stat stbuf;
|
|
|
|
int hflag= 0;
|
|
|
|
|
|
|
|
if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) {
|
|
|
|
|
|
|
|
/* >>> no boot image path given : no op */;
|
|
|
|
|
|
|
|
ret= 2; goto ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(xorriso->in_drive_handle == NULL)
|
|
|
|
hflag= 2;
|
|
|
|
ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
|
|
|
|
"on attempt to attach boot image", hflag);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
image= isoburn_get_attached_image(source_drive);
|
|
|
|
if(image == NULL) {
|
|
|
|
/* (should not happen) */
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"No ISO image present on attempt to attach boot image");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
ret= 0; goto ex;
|
|
|
|
}
|
|
|
|
if(flag & 2) {
|
|
|
|
iso_image_remove_boot_image(image);
|
|
|
|
xorriso->boot_count= 0;
|
|
|
|
ret= 1; goto ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
bin_path= xorriso->boot_image_bin_path;
|
|
|
|
emul= xorriso->boot_image_emul;
|
|
|
|
platform_id= xorriso->boot_platform_id;
|
|
|
|
load_size= xorriso->boot_image_load_size;
|
|
|
|
|
|
|
|
if(xorriso->boot_efi_default) {
|
|
|
|
emul= 0;
|
|
|
|
platform_id= 0xef;
|
|
|
|
xorriso->patch_isolinux_image= 0;
|
|
|
|
}
|
|
|
|
if(platform_id == 0xef || load_size < 0) {
|
|
|
|
ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
|
|
|
|
if(ret != 0)
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
load_size= ((stbuf.st_size / (off_t) 512) +
|
|
|
|
!!(stbuf.st_size % (off_t) 512)) * 512;
|
|
|
|
}
|
|
|
|
sprintf(xorriso->info_text, "Adding boot image ");
|
|
|
|
Text_shellsafe(bin_path, xorriso->info_text, 1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
|
|
|
|
|
|
|
|
if(emul == 0)
|
|
|
|
emul_type= ELTORITO_NO_EMUL;
|
|
|
|
else if(emul == 1)
|
|
|
|
emul_type= ELTORITO_HARD_DISC_EMUL;
|
|
|
|
else if(emul == 2)
|
|
|
|
emul_type= ELTORITO_FLOPPY_EMUL;
|
|
|
|
|
|
|
|
ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1);
|
|
|
|
if(ret <= 0) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Cannot find in ISO image: -boot_image ... bin_path=");
|
|
|
|
Text_shellsafe(bin_path, xorriso->info_text, 1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(xorriso->boot_count == 0) {
|
|
|
|
if(xorriso->boot_image_cat_path[0] == 0) {
|
|
|
|
strcpy(xorriso->boot_image_cat_path, bin_path);
|
|
|
|
cpt= strrchr(xorriso->boot_image_cat_path, '/');
|
|
|
|
if(cpt == NULL)
|
|
|
|
cpt= xorriso->boot_image_cat_path;
|
|
|
|
else
|
|
|
|
cpt++;
|
|
|
|
strcpy(cpt, "boot.cat");
|
|
|
|
}
|
|
|
|
ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
|
|
|
|
&node, 1);
|
|
|
|
if(ret > 0) {
|
|
|
|
if(!xorriso->do_overwrite) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"May not overwite existing -boot_image ... cat_path=");
|
|
|
|
Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
|
|
|
|
8 | (xorriso->do_overwrite == 1));
|
|
|
|
if(ret != 1) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Could not remove existing -boot_image cat_path=");
|
|
|
|
Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Discard old boot image, set new one */
|
|
|
|
ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
|
|
|
|
if(ret == 1)
|
|
|
|
iso_image_remove_boot_image(image);
|
|
|
|
ret= iso_image_set_boot_image(image, bin_path, emul_type,
|
|
|
|
xorriso->boot_image_cat_path, &bootimg);
|
|
|
|
if(ret > 0)
|
|
|
|
iso_image_set_boot_catalog_weight(image, 1000000000);
|
|
|
|
} else {
|
|
|
|
ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg);
|
|
|
|
}
|
|
|
|
if(ret < 0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when attaching El-Torito boot image to ISO 9660 image",
|
|
|
|
0, "FAILURE", 1);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Could not attach El-Torito boot image to ISO 9660 image");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
el_torito_set_boot_platform_id(bootimg, (uint8_t) platform_id);
|
|
|
|
el_torito_set_load_size(bootimg, load_size / 512);
|
|
|
|
el_torito_set_id_string(bootimg, xorriso->boot_id_string);
|
|
|
|
el_torito_set_selection_crit(bootimg, xorriso->boot_selection_crit);
|
|
|
|
ret= Xorriso_set_isolinux_options(xorriso, image, 1);
|
|
|
|
if(!(flag & 1)) {
|
|
|
|
/* Register attachment and reset even in case of error return */
|
|
|
|
xorriso->boot_count++;
|
|
|
|
xorriso->boot_platform_id= 0;
|
|
|
|
xorriso->patch_isolinux_image= 0;
|
|
|
|
xorriso->boot_image_bin_path[0]= 0;
|
|
|
|
xorriso->boot_image_bin_form[0]= 0;
|
|
|
|
xorriso->boot_image_emul= 0;
|
|
|
|
xorriso->boot_image_load_size= 4 * 512;
|
|
|
|
memset(xorriso->boot_id_string, 0, sizeof(xorriso->boot_id_string));
|
|
|
|
memset(xorriso->boot_selection_crit, 0,
|
|
|
|
sizeof(xorriso->boot_selection_crit));
|
|
|
|
xorriso->boot_efi_default= 0;
|
|
|
|
}
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
ret= 1;
|
|
|
|
ex:;
|
|
|
|
if(image != NULL)
|
|
|
|
iso_image_unref(image);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= do not write but only prepare and return size in sectors
|
|
|
|
*/
|
|
|
|
int Xorriso_write_session(struct XorrisO *xorriso, int flag)
|
|
|
|
{
|
|
|
|
int ret, relax= 0, i, pacifier_speed= 0, data_lba, ext, is_bootable= 0;
|
|
|
|
int freshly_bootable= 0, hide_attr, pad_by_libisofs= 0, signal_mode;
|
|
|
|
char *xorriso_id= NULL, *img_id, *sfe= NULL, *out_cs, *part_image;
|
|
|
|
struct isoburn_imgen_opts *sopts= NULL;
|
|
|
|
struct burn_drive_info *dinfo, *source_dinfo;
|
|
|
|
struct burn_drive *drive, *source_drive;
|
|
|
|
struct burn_disc *disc= NULL;
|
|
|
|
struct burn_write_opts *burn_options;
|
|
|
|
off_t readcounter= 0,writecounter= 0;
|
|
|
|
int num_sessions= 0, num_tracks= 0;
|
|
|
|
struct burn_session **sessions;
|
|
|
|
struct burn_track **tracks;
|
|
|
|
enum burn_disc_status s;
|
|
|
|
IsoImage *image= NULL;
|
|
|
|
IsoNode *root_node;
|
|
|
|
int profile_number;
|
|
|
|
char *profile_name= NULL;
|
|
|
|
IsoBoot *bootcat_node;
|
|
|
|
uint32_t padding;
|
|
|
|
|
|
|
|
Xorriso_alloc_meM(sfe, char, 5 * SfileadrL);
|
|
|
|
Xorriso_alloc_meM(xorriso_id, char, 256);
|
|
|
|
Xorriso_alloc_meM(profile_name, char, 80);
|
|
|
|
|
|
|
|
ret= Xorriso_finish_hl_update(xorriso, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
out_cs= xorriso->out_charset;
|
|
|
|
if(out_cs == NULL)
|
|
|
|
Xorriso_get_local_charset(xorriso, &out_cs, 0);
|
|
|
|
|
|
|
|
if(!(flag & 1)) {
|
|
|
|
ret= Xorriso_auto_format(xorriso, 0);
|
|
|
|
if(ret <=0 )
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
|
|
|
|
"on attempt to write", 2);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
s= isoburn_disc_get_status(drive);
|
|
|
|
if(xorriso->out_drive_handle == xorriso->in_drive_handle) {
|
|
|
|
if(abs(xorriso->displacement_sign) == 1 && xorriso->displacement != 0 &&
|
|
|
|
s != BURN_DISC_BLANK) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"May not grow ISO image while -displacement is non-zero");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
source_drive= drive;
|
|
|
|
} else {
|
|
|
|
if(xorriso->in_drive_handle == NULL) {
|
|
|
|
source_drive= drive;
|
|
|
|
} else {
|
|
|
|
ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
|
|
|
|
"on attempt to get source for write", 0);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
if(s!=BURN_DISC_BLANK) {
|
|
|
|
s= burn_disc_get_status(drive);
|
|
|
|
if(s!=BURN_DISC_BLANK)
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"-indev differs from -outdev and -outdev media is not blank");
|
|
|
|
else
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"-indev differs from -outdev and -outdev media holds non-zero data");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
|
|
|
|
if(ret == 2)
|
|
|
|
pacifier_speed= 1;
|
|
|
|
else if(ret == 3)
|
|
|
|
pacifier_speed= 2;
|
|
|
|
|
|
|
|
ret= isoburn_igopt_new(&sopts, 0);
|
|
|
|
if(ret<=0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso, 0);
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
relax= xorriso->relax_compliance;
|
|
|
|
|
|
|
|
xorriso->alignment= 0;
|
|
|
|
image= isoburn_get_attached_image(source_drive);
|
|
|
|
if(image != NULL) {
|
|
|
|
iso_image_set_application_id(image, xorriso->application_id);
|
|
|
|
iso_image_set_publisher_id(image, xorriso->publisher);
|
|
|
|
iso_image_set_system_id(image, xorriso->system_id);
|
|
|
|
iso_image_set_volset_id(image, xorriso->volset_id);
|
|
|
|
iso_image_set_copyright_file_id(image, xorriso->copyright_file);
|
|
|
|
iso_image_set_biblio_file_id(image, xorriso->biblio_file);
|
|
|
|
iso_image_set_abstract_file_id(image, xorriso->abstract_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if((xorriso->do_aaip & 256) && out_cs != NULL) {
|
|
|
|
static char *names = "isofs.cs";
|
|
|
|
size_t value_lengths[1];
|
|
|
|
|
|
|
|
value_lengths[0]= strlen(out_cs);
|
|
|
|
ret= Xorriso_setfattr(xorriso, NULL, "/",
|
|
|
|
(size_t) 1, &names, value_lengths, &out_cs, 2 | 8);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
/* Activate, adjust or discard boot image */
|
|
|
|
if(image!=NULL && !(flag&1)) {
|
|
|
|
is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node);
|
|
|
|
if(xorriso->boot_image_bin_path[0]) {
|
|
|
|
ret= Xorriso_attach_boot_image(xorriso, xorriso->boot_count == 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
freshly_bootable= 1;
|
|
|
|
}
|
|
|
|
if(xorriso->boot_count > 0) {
|
|
|
|
/* Eventually rename boot catalog node to changed boot_image_cat_path */
|
|
|
|
if(is_bootable > 0) {
|
|
|
|
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0);
|
|
|
|
if(ret > 0) {
|
|
|
|
if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) {
|
|
|
|
ret= Xorriso_rename(xorriso, NULL, sfe,
|
|
|
|
xorriso->boot_image_cat_path, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hide_attr= !!(xorriso->boot_image_cat_hidden);
|
|
|
|
if(xorriso->boot_image_cat_hidden & 1)
|
|
|
|
hide_attr|= LIBISO_HIDE_ON_RR;
|
|
|
|
if(xorriso->boot_image_cat_hidden & 2)
|
|
|
|
hide_attr|= LIBISO_HIDE_ON_JOLIET;
|
|
|
|
iso_image_set_boot_catalog_hidden(image, hide_attr);
|
|
|
|
} else if(xorriso->patch_isolinux_image & 1) {
|
|
|
|
if(is_bootable == 1) {
|
|
|
|
relax|= isoburn_igopt_allow_full_ascii;
|
|
|
|
sprintf(xorriso->info_text, "Patching boot info table");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
|
|
|
|
ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
|
|
|
|
sfe, 1);
|
|
|
|
if(ret < 0)
|
|
|
|
goto ex;
|
|
|
|
if(ret == 0) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Cannot patch boot image: no file found for its LBA.");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Probably the loaded boot image file was deleted in this session.");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Use -boot_image \"any\" \"discard\" or set new boot image");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
ret= Xorriso_set_isolinux_options(xorriso, image, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
} else if(!freshly_bootable) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Could not find any boot image for -boot_image patching");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
|
|
|
|
}
|
|
|
|
} else if(xorriso->keep_boot_image && is_bootable == 1) {
|
|
|
|
relax|= isoburn_igopt_allow_full_ascii;
|
|
|
|
sprintf(xorriso->info_text, "Keeping boot image unchanged");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
} else if(is_bootable == 1) {
|
|
|
|
iso_image_remove_boot_image(image);
|
|
|
|
sprintf(xorriso->info_text, "Discarded boot image from old session");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) {
|
|
|
|
/* Overwrite isofs.st of root node by xorriso->isofs_st_out */
|
|
|
|
char *name= "isofs.st";
|
|
|
|
char timestamp[16], *value= timestamp;
|
|
|
|
size_t value_length;
|
|
|
|
|
|
|
|
sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out);
|
|
|
|
value_length= strlen(timestamp);
|
|
|
|
Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name,
|
|
|
|
&value_length, &value, 2 | 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
isoburn_igopt_set_level(sopts, xorriso->iso_level);
|
|
|
|
ext= isoburn_igopt_rockridge |
|
|
|
|
((!!xorriso->do_joliet) * isoburn_igopt_joliet) |
|
|
|
|
((!!xorriso->do_iso1999) * isoburn_igopt_iso1999) |
|
|
|
|
(( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) |
|
|
|
|
(( (!(xorriso->ino_behavior & 2)) ||
|
|
|
|
(xorriso->do_aaip & (2 | 8 | 16 | 256)) ||
|
|
|
|
(xorriso->do_md5 & (2 | 4))
|
|
|
|
) * isoburn_igopt_aaip) |
|
|
|
|
((!!(xorriso->do_md5 & 2)) * isoburn_igopt_session_md5) |
|
|
|
|
((!!(xorriso->do_md5 & 4)) * isoburn_igopt_file_md5) |
|
|
|
|
((!!(xorriso->do_md5 & 8)) * isoburn_igopt_file_stability) |
|
|
|
|
((!!xorriso->do_old_empty) * isoburn_igopt_old_empty) |
|
|
|
|
((flag & 1) * isoburn_igopt_will_cancel);
|
|
|
|
if(xorriso->no_emul_toc & 1)
|
|
|
|
ext|= isoburn_igopt_no_emul_toc;
|
|
|
|
isoburn_igopt_set_extensions(sopts, ext);
|
|
|
|
isoburn_igopt_set_relaxed(sopts, relax);
|
|
|
|
ret= isoburn_igopt_set_untranslated_name_len(sopts,
|
|
|
|
xorriso->untranslated_name_len);
|
|
|
|
if(ret <= 0)
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
isoburn_igopt_set_sort_files(sopts, 1);
|
|
|
|
isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0);
|
|
|
|
isoburn_igopt_set_over_ugid(sopts, 2 * !!xorriso->do_global_uid,
|
|
|
|
2 * !!xorriso->do_global_gid,
|
|
|
|
(uid_t) xorriso->global_uid,
|
|
|
|
(gid_t) xorriso->global_gid);
|
|
|
|
isoburn_igopt_set_out_charset(sopts, out_cs);
|
|
|
|
isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048);
|
|
|
|
Ftimetxt(time(NULL), xorriso->scdbackup_tag_time, 8);
|
|
|
|
isoburn_igopt_set_scdbackup_tag(sopts, xorriso->scdbackup_tag_name,
|
|
|
|
xorriso->scdbackup_tag_time,
|
|
|
|
xorriso->scdbackup_tag_written);
|
|
|
|
for(i= 0; i < Xorriso_max_appended_partitionS; i++) {
|
|
|
|
if(xorriso->appended_partitions[i] == NULL)
|
|
|
|
continue;
|
|
|
|
if(xorriso->appended_partitions[i][0] == 0)
|
|
|
|
continue;
|
|
|
|
if(strcmp(xorriso->appended_partitions[i], ".") == 0)
|
|
|
|
part_image= "";
|
|
|
|
else
|
|
|
|
part_image= xorriso->appended_partitions[i];
|
|
|
|
isoburn_igopt_set_partition_img(sopts, i + 1,
|
|
|
|
xorriso->appended_part_types[i], part_image);
|
|
|
|
}
|
|
|
|
isoburn_igopt_set_disc_label(sopts, xorriso->ascii_disc_label);
|
|
|
|
|
|
|
|
if(image!=NULL && 12+strlen(Xorriso_timestamP)<80) {
|
|
|
|
strcpy(xorriso_id, xorriso->preparer_id);
|
|
|
|
img_id= (char *) iso_image_get_data_preparer_id(image);
|
|
|
|
if(img_id!=NULL) {
|
|
|
|
for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--);
|
|
|
|
if(i>0) {
|
|
|
|
sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'",
|
|
|
|
img_id);
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
iso_image_set_data_preparer_id(image, xorriso_id);
|
|
|
|
}
|
|
|
|
isoburn_igopt_set_pvd_times(sopts,
|
|
|
|
xorriso->vol_creation_time, xorriso->vol_modification_time,
|
|
|
|
xorriso->vol_expiration_time, xorriso->vol_effective_time,
|
|
|
|
xorriso->vol_uuid);
|
|
|
|
|
|
|
|
#ifdef Xorriso_with_libjtE
|
|
|
|
if(xorriso->libjte_handle && (xorriso->libjte_params_given & (4 | 8))) {
|
|
|
|
|
|
|
|
/* >>> Check whether the mandatory parameters are set */;
|
|
|
|
|
|
|
|
ret= libjte_set_outfile(xorriso->libjte_handle, xorriso->outdev);
|
|
|
|
Xorriso_process_msg_queues(xorriso, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto ex;
|
|
|
|
isoburn_igopt_attach_jte(sopts, xorriso->libjte_handle);
|
|
|
|
pad_by_libisofs= 1;
|
|
|
|
}
|
|
|
|
#endif /* Xorriso_with_libjtE */
|
|
|
|
|
|
|
|
if(xorriso->do_padding_by_libisofs || pad_by_libisofs) {
|
|
|
|
/* Padding to be done by libisofs, not by libburn.
|
|
|
|
*/
|
|
|
|
padding= xorriso->padding / 2048;
|
|
|
|
if((uint32_t) xorriso->padding > padding * 2048)
|
|
|
|
padding++;
|
|
|
|
/*
|
|
|
|
fprintf(stderr, "XORRISO_DEBUG: isoburn_igopt_set_tail_blocks(%d)\n",
|
|
|
|
(int) padding);
|
|
|
|
*/
|
|
|
|
isoburn_igopt_set_tail_blocks(sopts, padding);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make final abort check before starting expensive activities */
|
|
|
|
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
|
|
|
|
if(ret<0)
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
|
|
|
if(xorriso->zisofs_by_magic) {
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Checking disk file content for zisofs compression headers.");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
|
|
|
|
root_node= (IsoNode *) iso_image_get_root(image);
|
|
|
|
ret= iso_node_zf_by_magic(root_node,
|
|
|
|
(xorriso->out_drive_handle == xorriso->in_drive_handle) | 2 | 16);
|
|
|
|
if(ret<0) {
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when examining file content for zisofs headers",
|
|
|
|
0, "FAILURE", 1);
|
|
|
|
}
|
|
|
|
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
|
|
|
|
if(ret<0)
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
"Check for zisofs compression headers done.");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* >>> omit iso_image_update_sizes if the image was filled up very quickly */;
|
|
|
|
|
|
|
|
ret= iso_image_update_sizes(image);
|
|
|
|
if(ret < 0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso, 0);
|
|
|
|
if(ret<0) {
|
|
|
|
Xorriso_report_iso_error(xorriso, "", ret,
|
|
|
|
"Error when updating file sizes",
|
|
|
|
0, "FAILURE", 1);
|
|
|
|
}
|
|
|
|
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
|
|
|
|
if(ret<0)
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
|
|
|
|
Xorriso_set_abort_severity(xorriso, 1);
|
|
|
|
if (xorriso->grow_blindly_msc2 >= 0 &&
|
|
|
|
xorriso->out_drive_handle != xorriso->in_drive_handle) {
|
|
|
|
ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive,
|
|
|
|
xorriso->grow_blindly_msc2);
|
|
|
|
if(ret>0) {
|
|
|
|
/* Allow the consumer of output to access the input drive */
|
|
|
|
source_drive= NULL;
|
|
|
|
ret= Xorriso_give_up_drive(xorriso, 1|8);
|
|
|
|
if(ret<=0)
|
|
|
|
goto ex;
|
|
|
|
}
|
|
|
|
} else if(xorriso->out_drive_handle == xorriso->in_drive_handle ||
|
|
|
|
xorriso->in_drive_handle == NULL) {
|
|
|
|
ret= isoburn_prepare_disc(source_drive, &disc, sopts);
|
|
|
|
} else {
|
|
|
|
ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive);
|
|
|
|
}
|
|
|
|
if(ret <= 0) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
sprintf(xorriso->info_text,"Failed to prepare session write run");
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
|
|
|
|
if(ret<=0)
|
|
|
|
goto cancel_iso;
|
|
|
|
isoburn_igopt_get_effective_lba(sopts, &(xorriso->session_lba));
|
|
|
|
if(xorriso->do_stream_recording == 2) {
|
|
|
|
ret= isoburn_igopt_get_data_start(sopts, &data_lba);
|
|
|
|
if(ret > 0 && data_lba >= 16)
|
|
|
|
burn_write_opts_set_stream_recording(burn_options, data_lba);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1);
|
|
|
|
if(ret<=0 || (flag&1)) {
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
if(flag&1) /* set queue severity to FAILURE */
|
|
|
|
Xorriso_set_image_severities(xorriso, 2);
|
|
|
|
if(flag&1) /* reset queue severity */
|
|
|
|
Xorriso_set_image_severities(xorriso, 0);
|
|
|
|
goto cancel_iso;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret= Xorriso_may_burn(xorriso, 0);
|
|
|
|
if(ret <= 0)
|
|
|
|
goto cancel_iso;
|
|
|
|
|
|
|
|
/* Important: do not return until burn_is_aborting() was checked */
|
|
|
|
|
|
|
|
signal_mode= 1;
|
|
|
|
ret= burn_drive_get_drive_role(drive);
|
|
|
|
if(ret == 1)
|
|
|
|
signal_mode|= 2;
|
|
|
|
Xorriso_set_signal_handling(xorriso, signal_mode);
|
|
|
|
|
|
|
|
/* De-activate eventual target file truncation in dummy mode */
|
|
|
|
ret= isoburn_set_truncate(drive, (!xorriso->do_dummy) | 2 | 4);
|
|
|
|
if(ret < 0)
|
|
|
|
goto cancel_iso;
|
|
|
|
|
|
|
|
xorriso->run_state= 1; /* Indicate that burning has started */
|
|
|
|
isoburn_disc_write(burn_options, disc);
|
|
|
|
burn_write_opts_free(burn_options);
|
|
|
|
|
|
|
|
ret= Xorriso_pacifier_loop(xorriso, drive, pacifier_speed << 4);
|
|
|
|
if(burn_is_aborting(0))
|
|
|
|
Xorriso_abort(xorriso, 0); /* Never comes back */
|
|
|
|
Xorriso_set_signal_handling(xorriso, 0);
|
|