|
|
|
@ -890,6 +890,84 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70219 : API */
|
|
|
|
|
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|
|
|
|
char reasons[BURN_REASONS_LEN], int silent)
|
|
|
|
|
{
|
|
|
|
|
enum burn_write_types wt;
|
|
|
|
|
struct burn_drive *d = o->drive;
|
|
|
|
|
char msg[160], *reason_pt;
|
|
|
|
|
int no_media = 0;
|
|
|
|
|
|
|
|
|
|
reason_pt= reasons;
|
|
|
|
|
reasons[0] = 0;
|
|
|
|
|
|
|
|
|
|
/* check write mode against write job */
|
|
|
|
|
wt = burn_write_opts_auto_write_type(o, disc, reasons, 1);
|
|
|
|
|
if (wt == BURN_WRITE_NONE) {
|
|
|
|
|
if (strncmp(reasons, "MEDIA: ", 7)==0)
|
|
|
|
|
no_media = 1;
|
|
|
|
|
goto ex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(reasons, "%s: ", d->current_profile_text);
|
|
|
|
|
reason_pt= reasons + strlen(reasons);
|
|
|
|
|
if (d->status == BURN_DISC_UNSUITABLE)
|
|
|
|
|
goto unsuitable_profile;
|
|
|
|
|
if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
|
|
|
|
|
if (!burn_disc_write_is_ok(o, disc, (!!silent) << 1))
|
|
|
|
|
strcat(reasons, "unsuitable track mode found, ");
|
|
|
|
|
if (o->start_byte >= 0)
|
|
|
|
|
strcat(reasons, "write start address not supported, ");
|
|
|
|
|
} else if (d->current_profile == 0x1a || d->current_profile == 0x12) {
|
|
|
|
|
/* DVD+RW , DVD-RAM */
|
|
|
|
|
if (o->start_byte >= 0 && (o->start_byte % 2048))
|
|
|
|
|
strcat(reasons,
|
|
|
|
|
"write start address not properly aligned to 2048, ");
|
|
|
|
|
} else if (d->current_profile == 0x13) {
|
|
|
|
|
/* DVD-RW Restricted Overwrite */
|
|
|
|
|
if (o->start_byte >= 0 && (o->start_byte % 32768))
|
|
|
|
|
strcat(reasons,
|
|
|
|
|
"write start address not properly aligned to 32k, ");
|
|
|
|
|
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
|
|
|
|
d->current_profile == 0x15 ||
|
|
|
|
|
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
|
|
|
|
|
/* DVD-R* Sequential , DVD+R[/DL] */
|
|
|
|
|
if (o->start_byte >= 0)
|
|
|
|
|
strcat(reasons, "write start address not supported, ");
|
|
|
|
|
} else {
|
|
|
|
|
unsuitable_profile:;
|
|
|
|
|
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
|
|
|
|
|
d->current_profile, d->current_profile_text);
|
|
|
|
|
if (!silent)
|
|
|
|
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
|
|
|
0x0002011e,
|
|
|
|
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
msg, 0, 0);
|
|
|
|
|
strcat(reasons, "no suitable media profile detected, ");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
ex:;
|
|
|
|
|
if (reason_pt[0]) {
|
|
|
|
|
if (no_media) {
|
|
|
|
|
if (!silent)
|
|
|
|
|
libdax_msgs_submit(libdax_messenger,
|
|
|
|
|
d->global_index, 0x0002013a,
|
|
|
|
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
"No suitable media detected", 0, 0);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (!silent)
|
|
|
|
|
libdax_msgs_submit(libdax_messenger,
|
|
|
|
|
d->global_index, 0x00020139,
|
|
|
|
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
"Write job parameters are unsuitable", 0, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70129 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */
|
|
|
|
|
int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
|
|
|
|
struct burn_session *s, int tnum)
|
|
|
|
@ -931,6 +1009,46 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70226 */
|
|
|
|
|
int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|
|
|
|
struct burn_session *s, int tnum)
|
|
|
|
|
{
|
|
|
|
|
struct burn_drive *d = o->drive;
|
|
|
|
|
char msg[160];
|
|
|
|
|
int ret, lba, nwa;
|
|
|
|
|
off_t size;
|
|
|
|
|
|
|
|
|
|
ret = d->get_nwa(d, -1, &lba, &nwa);
|
|
|
|
|
sprintf(msg,
|
|
|
|
|
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
|
|
|
|
tnum+1, nwa, ret, d->nwa);
|
|
|
|
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
|
|
|
|
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
|
|
|
|
if (nwa > d->nwa)
|
|
|
|
|
d->nwa = nwa;
|
|
|
|
|
/* ts A70214 : eventually adjust already expanded size of track */
|
|
|
|
|
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
|
|
|
|
|
|
|
|
|
|
if (o->write_type == BURN_WRITE_SAO) {
|
|
|
|
|
/* Round track size up to 32 KiB and reserve track */
|
|
|
|
|
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
|
|
|
|
* (off_t) 2048;
|
|
|
|
|
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
|
|
|
|
ret = d->reserve_track(d, size);
|
|
|
|
|
if (ret <= 0) {
|
|
|
|
|
sprintf(msg, "Cannot reserve track of %.f bytes",
|
|
|
|
|
(double) size);
|
|
|
|
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
|
|
|
0x00020138,
|
|
|
|
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
msg, 0, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70129 */
|
|
|
|
|
int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
|
|
|
|
|
struct burn_session *s, int tnum)
|
|
|
|
@ -956,6 +1074,28 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70226 */
|
|
|
|
|
int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
|
|
|
|
|
struct burn_session *s, int tnum)
|
|
|
|
|
{
|
|
|
|
|
struct burn_drive *d = o->drive;
|
|
|
|
|
char msg[80];
|
|
|
|
|
|
|
|
|
|
sprintf(msg,
|
|
|
|
|
"Closing track %2.2d (absolute track and session number %d)",
|
|
|
|
|
tnum + 1, d->last_track_no);
|
|
|
|
|
libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
|
|
|
|
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
|
|
|
|
|
|
|
|
|
|
d->busy = BURN_DRIVE_CLOSING_SESSION;
|
|
|
|
|
d->close_track_session(d, 0, d->last_track_no); /* CLOSE TRACK, 001b */
|
|
|
|
|
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
|
|
|
|
|
d->busy = BURN_DRIVE_WRITING;
|
|
|
|
|
d->last_track_no++;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A61218 - A70129 */
|
|
|
|
|
int burn_dvd_write_track(struct burn_write_opts *o,
|
|
|
|
|
struct burn_session *s, int tnum)
|
|
|
|
@ -975,6 +1115,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|
|
|
|
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
goto ex;
|
|
|
|
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
|
|
|
|
/* DVD+R , DVD+R/DL */
|
|
|
|
|
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
goto ex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sectors = burn_track_get_sectors(t);
|
|
|
|
@ -1035,7 +1180,12 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|
|
|
|
d->current_profile == 0x15) {
|
|
|
|
|
/* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */
|
|
|
|
|
ret = burn_disc_close_track_dvd_minus_r(o, s, tnum);
|
|
|
|
|
if (ret != 2)
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
goto ex;
|
|
|
|
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
|
|
|
|
/* DVD+R , DVD+R/DL */
|
|
|
|
|
ret = burn_disc_close_track_dvd_plus_r(o, s, tnum);
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
goto ex;
|
|
|
|
|
}
|
|
|
|
|
ret = 1;
|
|
|
|
@ -1148,6 +1298,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
|
|
|
|
/* DVD+R , DVD+R/DL do each track as an own session */;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
@ -1258,76 +1410,30 @@ int burn_disc_setup_dvd_minus_r(struct burn_write_opts *o,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ts A70219 : API */
|
|
|
|
|
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|
|
|
|
char reasons[BURN_REASONS_LEN], int silent)
|
|
|
|
|
/* ts A70226 : for DVD+R , DVD+R/DL */
|
|
|
|
|
int burn_disc_setup_dvd_plus_r(struct burn_write_opts *o,
|
|
|
|
|
struct burn_disc *disc)
|
|
|
|
|
{
|
|
|
|
|
enum burn_write_types wt;
|
|
|
|
|
struct burn_drive *d = o->drive;
|
|
|
|
|
char msg[160], *reason_pt;
|
|
|
|
|
int no_media = 0;
|
|
|
|
|
|
|
|
|
|
reason_pt= reasons;
|
|
|
|
|
reasons[0] = 0;
|
|
|
|
|
/* most setup is in burn_disc_setup_track_dvd_plus_r() */;
|
|
|
|
|
|
|
|
|
|
/* check write mode against write job */
|
|
|
|
|
wt = burn_write_opts_auto_write_type(o, disc, reasons, 1);
|
|
|
|
|
if (wt == BURN_WRITE_NONE) {
|
|
|
|
|
if (strncmp(reasons, "MEDIA: ", 7)==0)
|
|
|
|
|
no_media = 1;
|
|
|
|
|
goto ex;
|
|
|
|
|
}
|
|
|
|
|
d->nwa = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(reasons, "%s: ", d->current_profile_text);
|
|
|
|
|
reason_pt= reasons + strlen(reasons);
|
|
|
|
|
if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
|
|
|
|
|
if (!burn_disc_write_is_ok(o, disc, (!!silent) << 1))
|
|
|
|
|
strcat(reasons, "unsuitable track mode found, ");
|
|
|
|
|
if (o->start_byte >= 0)
|
|
|
|
|
strcat(reasons, "write start address not supported, ");
|
|
|
|
|
} else if (d->current_profile == 0x1a || d->current_profile == 0x12) {
|
|
|
|
|
/* DVD+RW , DVD-RAM */
|
|
|
|
|
if (o->start_byte >= 0 && (o->start_byte % 2048))
|
|
|
|
|
strcat(reasons,
|
|
|
|
|
"write start address not properly aligned to 2048, ");
|
|
|
|
|
} else if (d->current_profile == 0x13) {
|
|
|
|
|
/* DVD-RW Restricted Overwrite */
|
|
|
|
|
if (o->start_byte >= 0 && (o->start_byte % 32768))
|
|
|
|
|
strcat(reasons,
|
|
|
|
|
"write start address not properly aligned to 32k, ");
|
|
|
|
|
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
|
|
|
|
d->current_profile == 0x15) {
|
|
|
|
|
/* DVD-R* Sequential */
|
|
|
|
|
if (o->start_byte >= 0)
|
|
|
|
|
strcat(reasons, "write start address not supported, ");
|
|
|
|
|
} else {
|
|
|
|
|
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
|
|
|
|
|
d->current_profile, d->current_profile_text);
|
|
|
|
|
if (!silent)
|
|
|
|
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
|
|
|
0x0002011e,
|
|
|
|
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
msg, 0, 0);
|
|
|
|
|
strcat(reasons, "no suitable media profile detected, ");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
ex:;
|
|
|
|
|
if (reason_pt[0]) {
|
|
|
|
|
if (no_media) {
|
|
|
|
|
if (!silent)
|
|
|
|
|
libdax_msgs_submit(libdax_messenger,
|
|
|
|
|
d->global_index, 0x0002013a,
|
|
|
|
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
"No suitable media detected", 0, 0);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (!silent)
|
|
|
|
|
libdax_msgs_submit(libdax_messenger,
|
|
|
|
|
d->global_index, 0x00020139,
|
|
|
|
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
"Write job parameters are unsuitable", 0, 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ts A70229 */
|
|
|
|
|
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
|
|
|
|
|
{
|
|
|
|
|
struct burn_drive *d = o->drive;
|
|
|
|
|
|
|
|
|
|
if (o->multi)
|
|
|
|
|
return 2;
|
|
|
|
|
d->busy = BURN_DRIVE_CLOSING_SESSION;
|
|
|
|
|
/* CLOSE SESSION, 101b, Finalize with minimal radius */
|
|
|
|
|
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
|
|
|
|
|
d->busy = BURN_DRIVE_WRITING;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1534,6 +1640,38 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|
|
|
|
/* ??? padding needed ??? cowardly doing it for now */
|
|
|
|
|
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
|
|
|
|
|
|
|
|
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
|
|
|
|
/* DVD+R , DVD+R/DL */
|
|
|
|
|
t = disc->session[0]->track[0];
|
|
|
|
|
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
|
|
|
|
|
default_size = burn_track_get_default_size(t);
|
|
|
|
|
|
|
|
|
|
#ifndef Libburn_precheck_write_ruleS
|
|
|
|
|
/* >>> oldfashioned checks hopefully never re-enabled */
|
|
|
|
|
#endif /* ! Libburn_precheck_write_ruleS */
|
|
|
|
|
|
|
|
|
|
if (o->write_type == BURN_WRITE_SAO && o_end) {
|
|
|
|
|
sprintf(msg, "Activated track default size %.f",
|
|
|
|
|
(double) default_size);
|
|
|
|
|
libdax_msgs_submit(libdax_messenger,
|
|
|
|
|
d->global_index, 0x0002012e,
|
|
|
|
|
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
msg, 0, 0);
|
|
|
|
|
burn_track_set_size(t, default_size);
|
|
|
|
|
}
|
|
|
|
|
ret = burn_disc_setup_dvd_plus_r(o, disc);
|
|
|
|
|
if (ret <= 0) {
|
|
|
|
|
sprintf(msg,
|
|
|
|
|
"Write preparation setup failed for DVD+R");
|
|
|
|
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
|
|
|
0x00020121,
|
|
|
|
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
|
|
|
msg, 0, 0);
|
|
|
|
|
goto early_failure;
|
|
|
|
|
}
|
|
|
|
|
/* ??? padding needed ??? cowardly doing it for now */
|
|
|
|
|
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
|
|
|
|
|
|
|
|
|
#ifndef Libburn_precheck_write_ruleS
|
|
|
|
|
/* <<< covered by burn_precheck_write() */
|
|
|
|
|
} else {
|
|
|
|
@ -1564,8 +1702,11 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|
|
|
|
d->progress.sectors = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* >>> eventual normal finalization measures */
|
|
|
|
|
|
|
|
|
|
if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
|
|
|
|
ret = burn_disc_finalize_dvd_plus_r(o);
|
|
|
|
|
if (ret <= 0)
|
|
|
|
|
goto ex;
|
|
|
|
|
}
|
|
|
|
|
ret = 1;
|
|
|
|
|
ex:;
|
|
|
|
|
|
|
|
|
|