New API calls isoburn_ropt_set_displacement(), isoburn_ropt_get_displacement()

This commit is contained in:
Thomas Schmitt 2010-11-30 09:39:44 +00:00
parent 82bff299ec
commit 668e58761b
7 changed files with 119 additions and 30 deletions

View File

@ -64,6 +64,20 @@ struct isoburn_cached_drive {
struct burn_drive *drive; struct burn_drive *drive;
struct isoburn_cache_tile tiles[Libisoburn_cache_tileS]; struct isoburn_cache_tile tiles[Libisoburn_cache_tileS];
int current_age; int current_age;
/**
Offset to be applied to all block addresses to compensate for an
eventual displacement of the block addresses relative to the image
start block address that was assumed when the image was created.
E.g. if track number 2 gets copied into a disk file and shall then
be loaded as ISO filesystem.
If displacement_sign is 1 then the displacement number will be
added to .read_block() addresses, if -1 it will be subtracted.
Else it will be ignored.
*/
uint32_t displacement;
int displacement_sign;
}; };
#define Libisoburn_max_agE 2000000000 #define Libisoburn_max_agE 2000000000
@ -105,6 +119,19 @@ int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
tiles = (struct isoburn_cache_tile *) icd->tiles; tiles = (struct isoburn_cache_tile *) icd->tiles;
if(icd->displacement_sign == 1) {
if(lba + icd->displacement < lba) {
address_rollover:;
return ISO_DISPLACE_ROLLOVER;
} else
lba += icd->displacement;
} else if(icd->displacement_sign == -1) {
if(lba < icd->displacement )
goto address_rollover;
else
lba -= icd->displacement;
}
aligned_lba= lba & ~(Libisoburn_tile_blockS - 1); aligned_lba= lba & ~(Libisoburn_tile_blockS - 1);
for(i=0; i<Libisoburn_cache_tileS; i++) { for(i=0; i<Libisoburn_cache_tileS; i++) {
@ -151,30 +178,10 @@ int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
if (ret > 0) if (ret > 0)
return 1; return 1;
tiles[oldest].last_error_lba = lba; tiles[oldest].last_error_lba = lba;
sprintf(msg, "ds_read_block(%lu) returns %lX",
#ifdef ISO_DATA_SOURCE_MISHAP (unsigned long) lba, (unsigned long) ret);
ret= ISO_DATA_SOURCE_MISHAP;
#else
/* <<< pre libisofs-0.6.7 */
/* It is not required by the specs of libisofs but implicitely assumed
...
But it is not possible to ignore FAILURE.
libisofs insists in original error codes, i.e. libisoburn cannot
change severity FAILURE associated with ISO_FILE_READ_ERROR.
So ISO_FILE_READ_ERROR is not an option and libisoburn has to
misuse ISO_FILE_CANT_WRITE, which is actually for image generation
and not for image reading.
This is quite wrong, although the error message text is unclear
enough to make it appear plausible.
*/
ret= ISO_FILE_CANT_WRITE;
#endif
if(ret >= 0)
ret = -1;
sprintf(msg, "ds_read_block(%lu) returns %d", (unsigned long) lba, ret);
isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "DEBUG", 0); isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "DEBUG", 0);
return ret; return ISO_DATA_SOURCE_MISHAP;
} }
#ifdef Libisoburn_read_cache_reporT #ifdef Libisoburn_read_cache_reporT
@ -226,7 +233,8 @@ int isoburn_data_source_shutdown(IsoDataSource *src, int flag)
} }
IsoDataSource *isoburn_data_source_new(struct burn_drive *d) IsoDataSource *isoburn_data_source_new(struct burn_drive *d,
uint32_t displacement, int displacement_sign)
{ {
IsoDataSource *ret; IsoDataSource *ret;
struct isoburn_cached_drive *icd= NULL; struct isoburn_cached_drive *icd= NULL;
@ -238,6 +246,7 @@ IsoDataSource *isoburn_data_source_new(struct burn_drive *d)
icd = calloc(1,sizeof(struct isoburn_cached_drive)); icd = calloc(1,sizeof(struct isoburn_cached_drive));
if (ret == NULL || icd == NULL) if (ret == NULL || icd == NULL)
return NULL; return NULL;
ret->version = 0;
ret->refcount = 1; ret->refcount = 1;
ret->read_block = ds_read_block; ret->read_block = ds_read_block;
ret->open = ds_open; ret->open = ds_open;
@ -253,6 +262,8 @@ IsoDataSource *isoburn_data_source_new(struct burn_drive *d)
icd->tiles[i].last_aligned_error_lba = 0xffffffff; icd->tiles[i].last_aligned_error_lba = 0xffffffff;
icd->tiles[i].age= 0; icd->tiles[i].age= 0;
} }
icd->displacement = displacement;
icd->displacement_sign = displacement_sign;
return ret; return ret;
} }

View File

@ -761,6 +761,8 @@ int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag)
o->hasElTorito= 0; o->hasElTorito= 0;
o->size= 0; o->size= 0;
o->pretend_blank= 1; o->pretend_blank= 1;
o->displacement= 0;
o->displacement_sign= 0;
return(1); return(1);
} }
@ -877,6 +879,24 @@ int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode)
} }
int isoburn_ropt_set_displacement(struct isoburn_read_opts *o,
uint32_t displacement, int displacement_sign)
{
o->displacement= displacement;
o->displacement_sign= displacement_sign;
return(1);
}
int isoburn_ropt_get_displacement(struct isoburn_read_opts *o,
uint32_t *displacement, int *displacement_sign)
{
*displacement= o->displacement;
*displacement_sign= o->displacement_sign;
return(1);
}
int isoburn_ropt_get_size_what(struct isoburn_read_opts *o, int isoburn_ropt_get_size_what(struct isoburn_read_opts *o,
uint32_t *size, int *has_what) uint32_t *size, int *has_what)
{ {

View File

@ -242,12 +242,15 @@ int isoburn_get_msc2(struct isoburn *o,
/** Get a data source suitable for read from a drive using burn_read_data() /** Get a data source suitable for read from a drive using burn_read_data()
function. function.
@param d drive to read from. Must be grabbed. @param d drive to read from. Must be grabbed.
@param displacement will be added or subtracted to any block address
@param displacement_sign +1 = add , -1= subtract , else keep unaltered
@return the data source, NULL on error. Must be freed with libisofs @return the data source, NULL on error. Must be freed with libisofs
iso_data_source_unref() function. Note: this doesn't release iso_data_source_unref() function. Note: this doesn't release
the drive. the drive.
*/ */
IsoDataSource * IsoDataSource *
isoburn_data_source_new(struct burn_drive *d); isoburn_data_source_new(struct burn_drive *d,
uint32_t displacement, int displacement_sign);
/** Disable read capabilities of a data source which was originally created /** Disable read capabilities of a data source which was originally created
by isoburn_data_source_new(). After this any attempt to read will yield by isoburn_data_source_new(). After this any attempt to read will yield
@ -332,6 +335,9 @@ struct isoburn_read_opts {
uint32_t size; /**< Will be filled with the size (in 2048 byte block) of uint32_t size; /**< Will be filled with the size (in 2048 byte block) of
* the image, as reported in the PVM. */ * the image, as reported in the PVM. */
unsigned int pretend_blank:1; /* always create empty image */ unsigned int pretend_blank:1; /* always create empty image */
uint32_t displacement;
int displacement_sign;
}; };

View File

@ -196,13 +196,32 @@ create_blank_image:;
goto create_blank_image; goto create_blank_image;
} }
if(read_opts->displacement != 0 && abs(read_opts->displacement_sign) == 1) {
/* Apply reverse displacement to session start */
if(read_opts->displacement_sign == -1) {
if(ms_block+ read_opts->displacement < ms_block) {
displacement_rollover:;
isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0);
return 0;
}
ms_block+= read_opts->displacement;
} else {
if(ms_block < read_opts->displacement)
goto displacement_rollover;
ms_block-= read_opts->displacement;
}
}
/* create the data source */ /* create the data source */
ret = iso_read_opts_new(&ropts, 0); ret = iso_read_opts_new(&ropts, 0);
if (ret < 0) { if (ret < 0) {
isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0); isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0);
return ret; return ret;
} }
/* Important: do not return until iso_read_opts_free() */ /* Important: do not return until iso_read_opts_free() */
iso_read_opts_set_start_block(ropts, ms_block); iso_read_opts_set_start_block(ropts, ms_block);
iso_read_opts_set_no_rockridge(ropts, read_opts->norock); iso_read_opts_set_no_rockridge(ropts, read_opts->norock);
iso_read_opts_set_no_aaip(ropts, read_opts->noaaip); iso_read_opts_set_no_aaip(ropts, read_opts->noaaip);
@ -221,7 +240,13 @@ create_blank_image:;
iso_read_opts_auto_input_charset(ropts, read_opts->auto_input_charset); iso_read_opts_auto_input_charset(ropts, read_opts->auto_input_charset);
iso_read_opts_load_system_area(ropts, 1); iso_read_opts_load_system_area(ropts, 1);
ds = isoburn_data_source_new(d); ds = isoburn_data_source_new(d, read_opts->displacement,
read_opts->displacement_sign);
if (ds == NULL) {
isoburn_report_iso_error(ret, "Cannot create IsoDataSource object", 0,
"FATAL", 0);
return ret;
}
if(o->iso_data_source!=NULL) if(o->iso_data_source!=NULL)
iso_data_source_unref(o->iso_data_source); iso_data_source_unref(o->iso_data_source);
o->iso_data_source= ds; o->iso_data_source= ds;

View File

@ -819,7 +819,6 @@ int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o,
mode_t *mode); mode_t *mode);
/** Set the character set for reading RR file names from ISO images. /** Set the character set for reading RR file names from ISO images.
@since 0.1.0 @since 0.1.0
@param o The option set to work on @param o The option set to work on
@ -834,6 +833,7 @@ int isoburn_ropt_set_input_charset(struct isoburn_read_opts *o,
int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o, int isoburn_ropt_get_input_charset(struct isoburn_read_opts *o,
char **input_charset); char **input_charset);
/** /**
Enable or disable methods to automatically choose an input charset. Enable or disable methods to automatically choose an input charset.
This eventually overrides the name set via isoburn_ropt_set_input_charset() This eventually overrides the name set via isoburn_ropt_set_input_charset()
@ -849,6 +849,30 @@ int isoburn_ropt_set_auto_incharset(struct isoburn_read_opts *o, int mode);
int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode); int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode);
/** Control an offset to be applied to all block addresses in order to
compensate for an eventual displacement of the image relative to the
start block address for which it was produced.
E.g. if track number 2 from CD gets copied into a disk file and shall then
be loaded as ISO filesystem, then the directory tree and all data file
content of the track copy will become readable by setting the track start
address as displacement and -1 as displacement_sign.
Data file content outside the track will of course not be accessible and
eventually produce read errors.
@since 0.6.6
@param o The option set to work on
@param displacement 0 or a positive number
@param displacement_sign Determines wether to add or subtract displacement
to block addresses before applying them to the
storage object for reading:
+1 = add , -1= subtract , else keep unaltered
*/
int isoburn_ropt_set_displacement(struct isoburn_read_opts *o,
uint32_t displacement, int displacement_sign);
int isoburn_ropt_get_displacement(struct isoburn_read_opts *o,
uint32_t *displacement, int *displacement_sign);
/** After calling function isoburn_read_image() there are informations /** After calling function isoburn_read_image() there are informations
available in the option set. available in the option set.
This info can be obtained as bits in parameter has_what. Like: This info can be obtained as bits in parameter has_what. Like:
@ -873,14 +897,15 @@ int isoburn_ropt_get_auto_incharset(struct isoburn_read_opts *o, int *mode);
#define isoburn_ropt_has_iso1999 4 #define isoburn_ropt_has_iso1999 4
#define isoburn_ropt_has_el_torito 8 #define isoburn_ropt_has_el_torito 8
int isoburn_ropt_get_size_what(struct isoburn_read_opts *o,
uint32_t *size, int *has_what);
/* ts A90122 */ /* ts A90122 */
/* >>> to be implemented: /* >>> to be implemented:
#define isoburn_ropt_has_acl 64 #define isoburn_ropt_has_acl 64
#define isoburn_ropt_has_ea 128 #define isoburn_ropt_has_ea 128
*/ */
int isoburn_ropt_get_size_what(struct isoburn_read_opts *o,
uint32_t *size, int *has_what);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */

View File

@ -70,6 +70,7 @@ isoburn_ropt_destroy;
isoburn_ropt_get_auto_incharset; isoburn_ropt_get_auto_incharset;
isoburn_ropt_get_default_dirperms; isoburn_ropt_get_default_dirperms;
isoburn_ropt_get_default_perms; isoburn_ropt_get_default_perms;
isoburn_ropt_get_displacement;
isoburn_ropt_get_extensions; isoburn_ropt_get_extensions;
isoburn_ropt_get_input_charset; isoburn_ropt_get_input_charset;
isoburn_ropt_get_size_what; isoburn_ropt_get_size_what;
@ -77,6 +78,7 @@ isoburn_ropt_new;
isoburn_ropt_set_auto_incharset; isoburn_ropt_set_auto_incharset;
isoburn_ropt_set_default_dirperms; isoburn_ropt_set_default_dirperms;
isoburn_ropt_set_default_perms; isoburn_ropt_set_default_perms;
isoburn_ropt_set_displacement;
isoburn_ropt_set_extensions; isoburn_ropt_set_extensions;
isoburn_ropt_set_input_charset; isoburn_ropt_set_input_charset;
isoburn_set_msc1; isoburn_set_msc1;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2010.11.27.134702" #define Xorriso_timestamP "2010.11.30.093929"