00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <stdio.h>
00016
00017 #ifndef Xorriso_standalonE
00018
00019 #include <libburn/libburn.h>
00020
00021 #include <libisofs/libisofs.h>
00022
00023 #else
00024
00025 #include "../libisofs/libisofs.h"
00026 #include "../libburn/libburn.h"
00027
00028 #endif
00029
00030 #define Libisoburn_with_aaiP yes
00031
00032 #include "isoburn.h"
00033 #include "libisoburn.h"
00034
00035 #define BP(a,b) [(b) - (a) + 1]
00036
00037 struct ecma119_pri_vol_desc
00038 {
00039 uint8_t vol_desc_type BP(1, 1);
00040 uint8_t std_identifier BP(2, 6);
00041 uint8_t vol_desc_version BP(7, 7);
00042 uint8_t unused1 BP(8, 8);
00043 uint8_t system_id BP(9, 40);
00044 uint8_t volume_id BP(41, 72);
00045 uint8_t unused2 BP(73, 80);
00046 uint8_t vol_space_size BP(81, 88);
00047 uint8_t unused3 BP(89, 120);
00048 uint8_t vol_set_size BP(121, 124);
00049 uint8_t vol_seq_number BP(125, 128);
00050 uint8_t block_size BP(129, 132);
00051 uint8_t path_table_size BP(133, 140);
00052 uint8_t l_path_table_pos BP(141, 144);
00053 uint8_t opt_l_path_table_pos BP(145, 148);
00054 uint8_t m_path_table_pos BP(149, 152);
00055 uint8_t opt_m_path_table_pos BP(153, 156);
00056 uint8_t root_dir_record BP(157, 190);
00057 uint8_t vol_set_id BP(191, 318);
00058 uint8_t publisher_id BP(319, 446);
00059 uint8_t data_prep_id BP(447, 574);
00060 uint8_t application_id BP(575, 702);
00061 uint8_t copyright_file_id BP(703, 739);
00062 uint8_t abstract_file_id BP(740, 776);
00063 uint8_t bibliographic_file_id BP(777, 813);
00064 uint8_t vol_creation_time BP(814, 830);
00065 uint8_t vol_modification_time BP(831, 847);
00066 uint8_t vol_expiration_time BP(848, 864);
00067 uint8_t vol_effective_time BP(865, 881);
00068 uint8_t file_structure_version BP(882, 882);
00069 uint8_t reserved1 BP(883, 883);
00070 uint8_t app_use BP(884, 1395);
00071 uint8_t reserved2 BP(1396, 2048);
00072 };
00073
00074 static
00075 uint32_t iso_read_lsb(const uint8_t *buf, int bytes)
00076 {
00077 int i;
00078 uint32_t ret = 0;
00079
00080 for (i=0; i<bytes; i++) {
00081 ret += ((uint32_t) buf[i]) << (i*8);
00082 }
00083 return ret;
00084 }
00085
00086
00087
00088
00089 IsoImage *isoburn_get_attached_image(struct burn_drive *d)
00090 {
00091 int ret;
00092 struct isoburn *o= NULL;
00093 ret = isoburn_find_emulator(&o, d, 0);
00094 if (ret < 0)
00095 return NULL;
00096
00097 if (o == NULL) {
00098 return NULL;
00099 }
00100 iso_image_ref(o->image);
00101 return o->image;
00102 }
00103
00104
00105 static void isoburn_idle_free_function(void *ignored)
00106 {
00107 return;
00108 }
00109
00110
00111
00112
00113 int isoburn_read_image(struct burn_drive *d,
00114 struct isoburn_read_opts *read_opts,
00115 IsoImage **image)
00116 {
00117 int ret, int_num, dummy;
00118 IsoReadOpts *ropts= NULL;
00119 IsoReadImageFeatures *features= NULL;
00120 uint32_t ms_block;
00121 char msg[160];
00122 enum burn_disc_status status= BURN_DISC_BLANK;
00123 IsoDataSource *ds= NULL;
00124 struct isoburn *o= NULL;
00125
00126 if(d != NULL) {
00127 ret = isoburn_find_emulator(&o, d, 0);
00128 if (ret < 0 || o == NULL)
00129 return 0;
00130 status = isoburn_disc_get_status(d);
00131 }
00132 if(read_opts==NULL) {
00133 isoburn_msgs_submit(o, 0x00060000,
00134 "Program error: isoburn_read_image: read_opts==NULL",
00135 0, "FATAL", 0);
00136 return(-1);
00137 }
00138 if (d == NULL || status == BURN_DISC_BLANK || read_opts->pretend_blank) {
00139 create_blank_image:;
00140
00141
00142
00143
00144 if (d == NULL) {
00145
00146 if (image==NULL) {
00147 isoburn_msgs_submit(o, 0x00060000,
00148 "Program error: isoburn_read_image: image==NULL",
00149 0, "FATAL", 0);
00150 return -1;
00151 }
00152
00153 ret = iso_image_new("ISOIMAGE", image);
00154 if (ret < 0) {
00155 isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0);
00156 return ret;
00157 }
00158 } else {
00159
00160 iso_image_unref(o->image);
00161 ret = iso_image_new("ISOIMAGE", &o->image);
00162 if (ret < 0) {
00163 isoburn_report_iso_error(ret, "Cannot create image", 0, "FATAL", 0);
00164 return ret;
00165 }
00166 if (image) {
00167 *image = o->image;
00168 iso_image_ref(*image);
00169 }
00170 }
00171 iso_image_set_ignore_aclea(*image,
00172 (!!(read_opts->noacl)) | ((!!read_opts->noea) << 1) );
00173 return 1;
00174 }
00175
00176 if (status != BURN_DISC_APPENDABLE && status != BURN_DISC_FULL) {
00177 isoburn_msgs_submit(o, 0x00060000,
00178 "Program error: isoburn_read_image: incorrect disc status",
00179 0, "FATAL", 0);
00180 return -4;
00181 }
00182
00183 memset((char *) &ropts, 0, sizeof(ropts));
00184
00185 ret = isoburn_disc_get_msc1(d, &int_num);
00186 if (ret <= 0)
00187 return -2;
00188 ms_block= int_num;
00189 ret = isoburn_read_iso_head(d, int_num, &dummy, NULL, 0);
00190 if (ret <= 0) {
00191 sprintf(msg, "No ISO 9660 image at LBA %d. Creating blank image.", int_num);
00192 isoburn_msgs_submit(o, 0x00060000, msg, 0, "WARNING", 0);
00193 goto create_blank_image;
00194 }
00195
00196
00197 ret = iso_read_opts_new(&ropts, 0);
00198 if (ret < 0) {
00199 isoburn_report_iso_error(ret, "Cannot create write opts", 0, "FATAL", 0);
00200 return ret;
00201 }
00202
00203 iso_read_opts_set_start_block(ropts, ms_block);
00204 iso_read_opts_set_no_rockridge(ropts, read_opts->norock);
00205
00206 #ifdef Libisoburn_with_aaiP
00207 iso_read_opts_set_no_aaip(ropts, read_opts->noaaip);
00208 #endif
00209
00210 iso_read_opts_set_no_joliet(ropts, read_opts->nojoliet);
00211 iso_read_opts_set_no_iso1999(ropts, read_opts->noiso1999);
00212 iso_read_opts_set_preferjoliet(ropts, read_opts->preferjoliet);
00213 iso_read_opts_set_default_permissions(ropts,
00214 read_opts->mode, read_opts->dirmode);
00215 iso_read_opts_set_default_uid(ropts, read_opts->uid);
00216 iso_read_opts_set_default_gid(ropts, read_opts->gid);
00217 iso_read_opts_set_input_charset(ropts, read_opts->input_charset);
00218
00219
00220
00221
00222
00223 ds = isoburn_data_source_new(d);
00224 if(o->iso_data_source!=NULL)
00225 iso_data_source_unref(o->iso_data_source);
00226 o->iso_data_source= ds;
00227 iso_image_attach_data(o->image, o->read_pacifier_handle,
00228 isoburn_idle_free_function);
00229 if(o->read_pacifier_handle==NULL)
00230 iso_tree_set_report_callback(o->image, NULL);
00231 else
00232 iso_tree_set_report_callback(o->image, o->read_pacifier);
00233 ret = iso_image_import(o->image, ds, ropts, &features);
00234 iso_tree_set_report_callback(o->image, NULL);
00235 iso_read_opts_free(ropts);
00236
00237 if (ret < 0) {
00238 isoburn_report_iso_error(ret, "Cannot import image", 0, "FAILURE", 0);
00239 return ret;
00240 }
00241
00242 if (image!=NULL) {
00243 *image = o->image;
00244 iso_image_ref(*image);
00245 }
00246 read_opts->hasRR = iso_read_image_features_has_rockridge(features);
00247 read_opts->hasJoliet = iso_read_image_features_has_joliet(features);
00248 read_opts->hasIso1999 = iso_read_image_features_has_iso1999(features);
00249 read_opts->hasElTorito = iso_read_image_features_has_eltorito(features);
00250 read_opts->size = iso_read_image_features_get_size(features);
00251 iso_read_image_features_destroy(features);
00252 return 1;
00253 }
00254
00255
00256
00257
00258 int isoburn_attach_image(struct burn_drive *d, IsoImage *image)
00259 {
00260 int ret;
00261 struct isoburn *o;
00262
00263 ret = isoburn_find_emulator(&o, d, 0);
00264 if (ret < 0 || o == NULL)
00265 return 0;
00266 if (image == NULL) {
00267 isoburn_msgs_submit(o, 0x00060000,
00268 "Program error: isoburn_attach_image: image==NULL",
00269 0, "FATAL", 0);
00270 return -1;
00271 }
00272 if(o->image != NULL)
00273 iso_image_unref(o->image);
00274 o->image = image;
00275 return(1);
00276 }
00277
00278
00279
00280
00281 int isoburn_activate_session(struct burn_drive *drive)
00282 {
00283 int ret;
00284 struct isoburn *o;
00285
00286 ret = isoburn_find_emulator(&o, drive, 0);
00287 if (ret < 0)
00288 return -1;
00289
00290 if (o->emulation_mode != 1)
00291 return 1;
00292 if (o->fabricated_msc2 >= 0)
00293 return 1;
00294
00295 if (!(o->fabricated_disc_status == BURN_DISC_APPENDABLE ||
00296 (o->fabricated_disc_status == BURN_DISC_BLANK &&
00297 o->zero_nwa > 0)))
00298 return 1;
00299
00300 ret = burn_random_access_write(drive, (off_t) 0, (char*)o->target_iso_head,
00301 Libisoburn_target_head_sizE, 1);
00302
00303 return ret;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313 int isoburn_start_emulation(struct isoburn *o, int flag)
00314 {
00315 int ret, i;
00316 off_t data_count;
00317 struct burn_drive *drive;
00318 struct ecma119_pri_vol_desc *pvm;
00319
00320 if(o==NULL) {
00321 isoburn_msgs_submit(NULL, 0x00060000,
00322 "Program error: isoburn_start_emulation: o==NULL",
00323 0, "FATAL", 0);
00324 return -1;
00325 }
00326
00327 drive= o->drive;
00328
00329
00330
00331 ret = burn_read_data(drive, (off_t) 0, (char*)o->target_iso_head,
00332 (off_t) Libisoburn_target_head_sizE, &data_count, 2);
00333
00334
00335 if (ret <= 0) {
00336 o->fabricated_disc_status= BURN_DISC_BLANK;
00337 return 1;
00338 }
00339
00340
00341
00342 i = Libisoburn_target_head_sizE;
00343 while (i && !o->target_iso_head[i-1])
00344 --i;
00345
00346 if (!i) {
00347 o->fabricated_disc_status= BURN_DISC_BLANK;
00348 return 1;
00349 }
00350
00351 pvm = (struct ecma119_pri_vol_desc *)(o->target_iso_head + 16 * 2048);
00352
00353 if (!strncmp((char*)pvm->std_identifier, "CD001", 5)) {
00354 off_t size;
00355
00356
00357 if (pvm->vol_desc_type[0] != 1 || pvm->vol_desc_version[0] != 1
00358 || pvm->file_structure_version[0] != 1 ) {
00359
00360 o->fabricated_disc_status= BURN_DISC_FULL;
00361 return 1;
00362 }
00363
00364
00365 size = (off_t) iso_read_lsb(pvm->vol_space_size, 4);
00366 size *= (off_t) 2048;
00367 isoburn_set_start_byte(o, size, 0);
00368 o->fabricated_disc_status= BURN_DISC_APPENDABLE;
00369 } else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) {
00370
00371
00372 isoburn_set_start_byte(o, o->zero_nwa * 2048, 0);
00373 o->fabricated_disc_status= BURN_DISC_BLANK;
00374 } else {
00375
00376 o->fabricated_disc_status= BURN_DISC_FULL;
00377 }
00378 return 1;
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 int isoburn_invalidate_iso(struct isoburn *o, int flag)
00391 {
00392
00393
00394
00395
00396 strncpy((char*)o->target_iso_head + 16 * 2048 + 1, "CDXX1", 5);
00397 return isoburn_activate_session(o->drive);
00398 }
00399
00400
00401
00402 int isoburn_set_read_pacifier(struct burn_drive *drive,
00403 int (*read_pacifier)(IsoImage*, IsoFileSource*),
00404 void *read_handle)
00405 {
00406 int ret;
00407 struct isoburn *o;
00408
00409 ret = isoburn_find_emulator(&o, drive, 0);
00410 if(ret < 0 || o == NULL)
00411 return -1;
00412 o->read_pacifier_handle= read_handle;
00413 o->read_pacifier= read_pacifier;
00414 return(1);
00415 }
00416