From 668e58761b810bc594e5b4c7cabd61796c9677de Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 30 Nov 2010 09:39:44 +0000 Subject: [PATCH] New API calls isoburn_ropt_set_displacement(), isoburn_ropt_get_displacement() --- libisoburn/data_source.c | 59 ++++++++++++++++++++++--------------- libisoburn/isoburn.c | 20 +++++++++++++ libisoburn/isoburn.h | 8 ++++- libisoburn/isofs_wrap.c | 27 ++++++++++++++++- libisoburn/libisoburn.h | 31 +++++++++++++++++-- libisoburn/libisoburn.ver | 2 ++ xorriso/xorriso_timestamp.h | 2 +- 7 files changed, 119 insertions(+), 30 deletions(-) diff --git a/libisoburn/data_source.c b/libisoburn/data_source.c index d711b1c0..f478265f 100644 --- a/libisoburn/data_source.c +++ b/libisoburn/data_source.c @@ -64,6 +64,20 @@ struct isoburn_cached_drive { struct burn_drive *drive; struct isoburn_cache_tile tiles[Libisoburn_cache_tileS]; 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 @@ -105,6 +119,19 @@ int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer) 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); for(i=0; i 0) return 1; tiles[oldest].last_error_lba = lba; - -#ifdef ISO_DATA_SOURCE_MISHAP - 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); + sprintf(msg, "ds_read_block(%lu) returns %lX", + (unsigned long) lba, (unsigned long) ret); isoburn_msgs_submit(NULL, 0x00060000, msg, 0, "DEBUG", 0); - return ret; + return ISO_DATA_SOURCE_MISHAP; } #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; 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)); if (ret == NULL || icd == NULL) return NULL; + ret->version = 0; ret->refcount = 1; ret->read_block = ds_read_block; 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].age= 0; } + icd->displacement = displacement; + icd->displacement_sign = displacement_sign; return ret; } diff --git a/libisoburn/isoburn.c b/libisoburn/isoburn.c index 51805f28..775e1e6b 100644 --- a/libisoburn/isoburn.c +++ b/libisoburn/isoburn.c @@ -761,6 +761,8 @@ int isoburn_ropt_new(struct isoburn_read_opts **new_o, int flag) o->hasElTorito= 0; o->size= 0; o->pretend_blank= 1; + o->displacement= 0; + o->displacement_sign= 0; 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, uint32_t *size, int *has_what) { diff --git a/libisoburn/isoburn.h b/libisoburn/isoburn.h index 0304cb37..44138707 100644 --- a/libisoburn/isoburn.h +++ b/libisoburn/isoburn.h @@ -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() function. @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 iso_data_source_unref() function. Note: this doesn't release the drive. */ 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 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 * the image, as reported in the PVM. */ unsigned int pretend_blank:1; /* always create empty image */ + + uint32_t displacement; + int displacement_sign; }; diff --git a/libisoburn/isofs_wrap.c b/libisoburn/isofs_wrap.c index 7e6164c1..9efc6c43 100644 --- a/libisoburn/isofs_wrap.c +++ b/libisoburn/isofs_wrap.c @@ -196,13 +196,32 @@ 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 */ ret = iso_read_opts_new(&ropts, 0); if (ret < 0) { isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0); return ret; } + /* Important: do not return until iso_read_opts_free() */ + iso_read_opts_set_start_block(ropts, ms_block); iso_read_opts_set_no_rockridge(ropts, read_opts->norock); 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_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) iso_data_source_unref(o->iso_data_source); o->iso_data_source= ds; diff --git a/libisoburn/libisoburn.h b/libisoburn/libisoburn.h index c1eca2b4..1c790d34 100644 --- a/libisoburn/libisoburn.h +++ b/libisoburn/libisoburn.h @@ -819,7 +819,6 @@ int isoburn_ropt_get_default_dirperms(struct isoburn_read_opts *o, mode_t *mode); - /** Set the character set for reading RR file names from ISO images. @since 0.1.0 @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, char **input_charset); + /** Enable or disable methods to automatically choose an 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); +/** 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 available in the option set. 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_el_torito 8 +int isoburn_ropt_get_size_what(struct isoburn_read_opts *o, + uint32_t *size, int *has_what); + /* ts A90122 */ /* >>> to be implemented: #define isoburn_ropt_has_acl 64 #define isoburn_ropt_has_ea 128 */ -int isoburn_ropt_get_size_what(struct isoburn_read_opts *o, - uint32_t *size, int *has_what); /* ----------------------------------------------------------------------- */ diff --git a/libisoburn/libisoburn.ver b/libisoburn/libisoburn.ver index 5c1b25b7..c2a60c90 100644 --- a/libisoburn/libisoburn.ver +++ b/libisoburn/libisoburn.ver @@ -70,6 +70,7 @@ isoburn_ropt_destroy; isoburn_ropt_get_auto_incharset; isoburn_ropt_get_default_dirperms; isoburn_ropt_get_default_perms; +isoburn_ropt_get_displacement; isoburn_ropt_get_extensions; isoburn_ropt_get_input_charset; isoburn_ropt_get_size_what; @@ -77,6 +78,7 @@ isoburn_ropt_new; isoburn_ropt_set_auto_incharset; isoburn_ropt_set_default_dirperms; isoburn_ropt_set_default_perms; +isoburn_ropt_set_displacement; isoburn_ropt_set_extensions; isoburn_ropt_set_input_charset; isoburn_set_msc1; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index f91c491f..38a71be8 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2010.11.27.134702" +#define Xorriso_timestamP "2010.11.30.093929"