diff --git a/xorriso/findjob.c b/xorriso/findjob.c index 0fa8721c..e508da18 100644 --- a/xorriso/findjob.c +++ b/xorriso/findjob.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2015 Thomas Schmitt, + Copyright 2007-2016 Thomas Schmitt, Provided under GPL version 2 or later. @@ -1108,6 +1108,14 @@ int Findjob_get_found_path(struct FindjoB *o, char **path, int flag) } +int Findjob_get_last_data_file_block(struct FindjoB *o, uint32_t *lba, + int flag) +{ + *lba= o->last_data_file_block; + return(1); +} + + int Findjob_get_action(struct FindjoB *o, int flag) { return(o->action); diff --git a/xorriso/findjob.h b/xorriso/findjob.h index d383d5bc..512fac0f 100644 --- a/xorriso/findjob.h +++ b/xorriso/findjob.h @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2015 Thomas Schmitt, + Copyright 2007-2016 Thomas Schmitt, Provided under GPL version 2 or later. @@ -181,6 +181,7 @@ struct FindjoB { result delivered in XorrisO.find_unique_trunc_result 56= like 54 but tolerating existing truncated names 57= like 55 but tolerating existing truncated names + 58= internal: last_data_file_block */ int action; int prune; @@ -199,6 +200,7 @@ struct FindjoB { off_t estim_upper_size; off_t estim_lower_size; struct FindjoB *subjob; + uint32_t last_data_file_block; /* Errors */ char errmsg[4096]; @@ -365,6 +367,9 @@ int Findjob_set_found_path(struct FindjoB *o, char *path, int flag); int Findjob_get_found_path(struct FindjoB *o, char **path, int flag); +int Findjob_get_last_data_file_block(struct FindjoB *o, uint32_t *lba, + int flag); + #else /* Xorriso_findjob_on_expR */ @@ -442,6 +447,9 @@ int Findjob_set_found_path(struct FindjoB *o, char *path, int flag); int Findjob_get_found_path(struct FindjoB *o, char **path, int flag); +int Findjob_get_last_data_file_block(struct FindjoB *o, uint32_t *lba, + int flag); + #endif /* ! Xorriso_findjob_on_expR */ diff --git a/xorriso/iso_img.c b/xorriso/iso_img.c index cc1ebe1a..07f8dabe 100644 --- a/xorriso/iso_img.c +++ b/xorriso/iso_img.c @@ -1527,6 +1527,31 @@ struct elto_img_par { }; +/* @param ptype 0= unknown, 1= gpt-basdat, 2=gpt-hfsplus, 3=EFI + @param flag bit0= isohybrid +*/ +static int Xorriso_register_eltorito_gpt(struct XorrisO *xorriso, + struct elto_img_par *et_img, + int ptype, + int *efi_boot_part, int *first_efi, + int flag) +{ + if(flag & 1) { + if(ptype == 1 || ptype == 3) + et_img->do_gpt_basdat= 1; + else if(ptype == 2) + et_img->do_gpt_hfsplus= 1; + return(1); + } else if(*first_efi && et_img->platform_id == 0xef) { + *efi_boot_part= 1; + return(1); + } + if(et_img->platform_id == 0xef) + *first_efi= 0; + return(0); +} + + /* @param ptype 0= unknown, 1= gpt-basdat, 2=gpt-hfsplus, 3=EFI @param flag bit0= isohybrid */ @@ -1536,23 +1561,15 @@ static int Xorriso_search_eltorito_path(struct XorrisO *xorriso, int *found, int *efi_boot_part, int flag) { - int first_efi= 1, et_idx; + int first_efi= 1, et_idx, ret; for(et_idx= 0; et_idx < elto_count; et_idx++) { if(strcmp(et_imgs[et_idx].path, path) != 0) continue; - if(flag & 1) { - if(ptype == 1 || ptype == 3) - et_imgs[et_idx].do_gpt_basdat= 1; - else if(ptype == 2) - et_imgs[et_idx].do_gpt_hfsplus= 1; + ret= Xorriso_register_eltorito_gpt(xorriso, et_imgs + et_idx, + ptype, efi_boot_part, &first_efi, flag); + if(ret > 0) break; - } else if(first_efi && et_imgs[et_idx].platform_id == 0xef) { - *efi_boot_part= 1; - break; - } - if(et_imgs[et_idx].platform_id == 0xef) - first_efi= 0; } *found= et_idx; if(et_idx < elto_count) @@ -1561,7 +1578,51 @@ static int Xorriso_search_eltorito_path(struct XorrisO *xorriso, } +static int Xorriso_search_eltorito_lba(struct XorrisO *xorriso, + struct elto_img_par *et_imgs, + int elto_count, + unsigned int lba, + int *found, int flag) +{ + int et_idx; + + for(et_idx= 0; et_idx < elto_count; et_idx++) + if(et_imgs[et_idx].lba == lba) + break; + *found= et_idx; + if(et_idx < elto_count) + return(1); + return(0); +} + + +int Xorriso_highest_data_block(struct XorrisO *xorriso, uint32_t *high_block, + int flag) +{ + int ret; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + *high_block= 0; + ret= Findjob_new(&job, "/", 0); + if(ret <= 0) { + Xorriso_no_findjob(xorriso, "[internal:last_data_file_block]", 0); + {ret= -1; goto ex;} + } + Findjob_set_action_type(job, 58, 0, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, + NULL, "/", &dir_stbuf, 0, 0); + if(ret <= 0) + goto ex; + Findjob_get_last_data_file_block(job, high_block, 0); +ex:; + Findjob_destroy(&job, 0); + return(ret); +} + + /* @param flag bit0= do not record but only count + bit1= as_mkisofs */ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, char **et_lines, int et_line_count, @@ -1569,14 +1630,15 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, char **cmds, int *cmd_count, int flag) { int ret= 0, i, num_count, mkisofs, line_count, idx, et_idx, isohybrid= 0; - int ptype, gpt_idx, j, pad; - int efi_boot_part= 0, full_sparc_part= 0, have_sparc_part= 0; + int ptype, gpt_idx, j, pad, mbr_idx; + int efi_boot_part= 0, full_sparc_part= 0, have_sparc_part= 0, fe_dummy= 1; int appended_as_gpt= 0, have_prep= 0, did_sysarea= 0, cared_for_apm= 0; int cared_for_sparc= 0, have_hfsplus= 0; int have_sysarea= 0, ptable_killer, imported_iso, have_alpha_ldr_path= 0; - int have_protective_msdos= 0; + int have_protective_msdos= 0, appended_partition= 0, part_like_isohybrid= 0; unsigned long int sa_options= 0, partno, id_tag, perms, start_cyl, num_blocks; unsigned long int part_status, part_type, start_block; + uint32_t high_block= 0; char name[24], *textpt, *contentpt, *buf= NULL; char **lines= NULL; double num[8]; @@ -1595,14 +1657,18 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, uint64_t start_block; uint64_t block_count; int appended; + int has_path; }; struct mbr_par *mbrpts= NULL; int mbr_count= 0; struct gpt_par { int ptype; /* 0= unknown, 1= gpt-basdat, 2=gpt-hfsplus, 3=EFI */ + int is_gap; int has_path; char *path; + uint64_t start_block; + uint64_t block_count; }; struct gpt_par *gpts= NULL; int gpt_count= 0; @@ -1672,6 +1738,12 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } } + ret= Xorriso_highest_data_block(xorriso, &high_block, 0); + if(ret < 0) + goto ex; + if(ret == 0) + high_block = img_blocks - 1; + if(elto_count > 0) { Xorriso_alloc_meM(et_imgs, struct elto_img_par, elto_count); for(et_idx= 0; et_idx < elto_count; et_idx++) { @@ -1812,6 +1884,10 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, if(num_blocks > 0 && start_block + num_blocks > mbr_parts_end) mbr_parts_end= start_block + num_blocks; + } else if(strcmp(name, "MBR partition path :") == 0) { + idx= num[0] - 1; + mbrpts[idx].has_path= 1; + } else if(strcmp(name, "GPT type GUID :") == 0) { idx= num[0] - 1; if(strcmp(textpt, "a2a0d0ebe5b9334487c068b6b72699c7") == 0) @@ -1827,14 +1903,19 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, idx= num[0] - 1; if(img_blocks <= num[1] && num[2] > 0) appended_as_gpt= 1; - - /* >>> ??? can there be independent partitions inside the image ? */; + gpts[idx].start_block= num[1]; + gpts[idx].block_count= num[2]; } else if(strcmp(name, "GPT partition path :") == 0) { idx= num[0] - 1; gpts[idx].has_path= 1; gpts[idx].path= textpt; + } else if(strcmp(name, "GPT partition name :") == 0) { + idx= num[0] - 1; + if(strstr(contentpt, " 470061007000") != NULL) /* "Gap"... */ + gpts[idx].is_gap= 1; + } else if(strcmp(name, "APM partition name :") == 0) { idx= num[0] - 1; if(strcmp(textpt, "HFSPLUS_Hybrid") == 0) @@ -1855,6 +1936,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } } + if(!have_protective_msdos) + appended_as_gpt= 0; + /* Second pass: scan for System Area info */ for(i= 0; i < line_count; i++) { buf[0]= 0; @@ -1953,6 +2037,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, imported_iso); if(partno >= 1 && (int) partno <= mbr_count) mbrpts[partno - 1].appended= 1; + appended_partition= 1; } } else if(part_type == 0x41 && have_prep) { if(mkisofs) { @@ -2041,19 +2126,49 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, part_type= 0xef; else part_type= 0xcd; - if(img_blocks <= num[1] && num[2] > 0) { - if(appended_as_gpt == 1) { - if(mkisofs) - sprintf(buf, "-appended_part_as_gpt"); - else - sprintf(buf, "-boot_image any appended_part_as=gpt"); - Xorriso_record_cmd_linE - appended_as_gpt= 2; + + if(high_block < num[1] && num[2] > 0 && !gpts[idx].is_gap) { + for(mbr_idx = 0; mbr_idx < mbr_count; mbr_idx++) { + if(mbrpts[mbr_idx].start_block == num[1] && + mbrpts[mbr_idx].block_count == num[2]) + break; + } + if(mbr_idx >= mbr_count) { + if(appended_as_gpt == 1) { + if(mkisofs) + sprintf(buf, "-appended_part_as_gpt"); + else + sprintf(buf, "-boot_image any appended_part_as=gpt"); + Xorriso_record_cmd_linE + appended_as_gpt= 2; + } + sprintf(buf, "-append_partition %d 0x%lx ", idx + 1, part_type); + Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) num[1], + (uint64_t) (num[1] + num[2] - 1.0), "d", + imported_iso); + appended_partition= 1; + } + + ret= Xorriso_search_eltorito_lba(xorriso, et_imgs, elto_count, + (unsigned int) (num[1] / 4.0), + &et_idx, 0); + if(ret > 0) { + if(!(et_imgs[et_idx].do_gpt_basdat || + et_imgs[et_idx].do_gpt_hfsplus || + part_like_isohybrid)) { + if(mkisofs) + sprintf(buf, "-part_like_isohybrid"); + else + sprintf(buf, "-boot_image any part_like_isohybrid=on"); + Xorriso_record_cmd_linE + buf[0]= 0; + part_like_isohybrid= 1; + } + /* mark el torito for -isohybrid-gpt-... */ + Xorriso_register_eltorito_gpt(xorriso, et_imgs + et_idx, + gpts[idx].ptype, &efi_boot_part, + &fe_dummy, 1); } - sprintf(buf, "-append_partition %d 0x%lx ", idx + 1, part_type); - Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) num[1], - (uint64_t) (num[1] + num[2] - 1.0), "d", - imported_iso); } else if(gpts[idx].ptype == 3 && gpts[idx].has_path == 0 && img_blocks >= num[1] + num[2] && !efi_boot_part) { @@ -2312,6 +2427,68 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, sprintf(buf, "-boot_image any next"); Xorriso_record_cmd_linE } + if(et_imgs[idx].path[0] == 0) { + + /* >>> need way to eploit El Torito img blks : */; + + /* Check whether appended partition */; + for(i= 0; i < mbr_count; i++) + if((mbrpts[i].appended || !mbrpts[i].has_path) && + mbrpts[i].start_block == ((uint64_t) et_imgs[idx].lba) * 4 && + (mbrpts[i].block_count == (uint64_t) et_imgs[idx].ldsiz || + et_imgs[idx].ldsiz == 0 || et_imgs[idx].ldsiz == 1)) + break; + if (i < mbr_count) { + if(!mbrpts[i].appended) { + mbrpts[i].appended= 1; + if(!appended_as_gpt) { + sprintf(buf, "-append_partition %lu 0x%lx ", (unsigned long) i + 1, + (unsigned long) mbrpts[i].ptype); + Xorriso_add_intvl_adr(xorriso, buf, + (uint64_t) mbrpts[i].start_block, + ((uint64_t) mbrpts[i].start_block) + + mbrpts[i].block_count - 1, + "d", imported_iso); + Xorriso_record_cmd_linE + appended_partition= 1; + buf[0]= 0; + } + } + sprintf(app_pseudo_paths[idx], + "--interval:appended_partition_%d_start_%lus_size_%lud:all::", + i + 1, + (unsigned long) et_imgs[idx].lba, + (unsigned long) mbrpts[i].block_count); + et_imgs[idx].path= app_pseudo_paths[idx]; + } + if (et_imgs[idx].path[0] == 0) { + for(i= 0; i < gpt_count; i++) { + if(have_protective_msdos && ( + gpts[i].start_block == ((uint64_t) et_imgs[idx].lba) * 4 && + (gpts[i].block_count == (uint64_t) et_imgs[idx].ldsiz || + et_imgs[idx].ldsiz == 0 || et_imgs[idx].ldsiz == 1))) + break; + } + if (i < gpt_count) { + sprintf(app_pseudo_paths[idx], + "--interval:appended_partition_%d_start_%lus_size_%lud:all::", + i + 1, + (unsigned long) et_imgs[idx].lba, + (unsigned long) gpts[i].block_count); + et_imgs[idx].path= app_pseudo_paths[idx]; + } + } + if (et_imgs[idx].path[0] == 0) { + if(!(flag & 1)) { + sprintf(xorriso->info_text, + "Cannot enable EL Torito boot image #%d because it is not a data file in the ISO filesystem", + idx + 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + } + buf[0]= 0; + continue; + } + } if(et_imgs[idx].platform_id == 0) { if(mkisofs) sprintf(buf, "-b "); @@ -2328,36 +2505,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, "Cannot enable EL Torito boot image #%d because Platform Id 0x%2.2x cannot be expressed in mkisofs emulation", idx + 1, et_imgs[idx].platform_id); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - continue; - } - } - if(et_imgs[idx].path[0] == 0) { - - /* >>> need way to eploit El Torito img blks : */; - - /* Check whether appended partition */; - for(i= 0; i < mbr_count; i++) - if(mbrpts[i].appended && - mbrpts[i].start_block == ((uint64_t) et_imgs[idx].lba) * 4 && - (mbrpts[i].block_count == (uint64_t) et_imgs[idx].ldsiz || - et_imgs[idx].ldsiz == 0 || et_imgs[idx].ldsiz == 1)) - break; - if (i < mbr_count) { - sprintf(app_pseudo_paths[idx], - "--interval:appended_partition_%d_start_%lus_size_%lud:all::", - i + 1, - (unsigned long) et_imgs[idx].lba, - (unsigned long) mbrpts[i].block_count); - et_imgs[idx].path= app_pseudo_paths[idx]; - - } else { - if(!(flag & 1)) { - sprintf(xorriso->info_text, - "Cannot enable EL Torito boot image #%d because it is not a data file in the ISO filesystem", - idx + 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - } - buf[0]= 0; continue; } } @@ -2453,6 +2600,14 @@ after_el_torito: Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } + if(appended_partition) { + if(mkisofs) + sprintf(buf, "-no-pad"); + else + sprintf(buf, "-padding 0"); + Xorriso_record_cmd_linE + } + ret= 1; ex: xorriso->show_hfs_cmds= NULL; diff --git a/xorriso/iso_manip.c b/xorriso/iso_manip.c index 6bdfbe29..c1da8d52 100644 --- a/xorriso/iso_manip.c +++ b/xorriso/iso_manip.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2015 Thomas Schmitt, + Copyright 2007-2016 Thomas Schmitt, Provided under GPL version 2 or later. @@ -2632,7 +2632,8 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } else if(action == 21) { /* report_damage */ ret= Xorriso_report_damage(xorriso, show_path, node, 0); } else if(action == 22) { - ret= Xorriso_report_lba(xorriso, show_path, node, 0); + ret= Xorriso_report_lba(xorriso, show_path, node, + &job->last_data_file_block, 0); } else if(action == 23) { /* internal: memorize path of last matching node */ ret= Findjob_set_found_path(job, show_path, 0); } else if(action == 24) { @@ -2813,7 +2814,8 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, return(ret); } else if(action == 51) { /* report_sections */ - ret= Xorriso_report_lba(xorriso, show_path, node, 1); + ret= Xorriso_report_lba(xorriso, show_path, node, + &job->last_data_file_block, 1); } else if(action == 53) { /* internal: show_hfs_cmd */ ret= Xorriso_get_blessing(xorriso, node, &bless_idx, bless_code, 0); @@ -2874,6 +2876,10 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, ret= Xorriso_truncate_uniquely(xorriso, type, node, abs_path, show_path, 1 | (2 * (action == 57))); + } else if(action == 58) { /* internal: last_data_file_block */ + ret= Xorriso_report_lba(xorriso, show_path, node, + &job->last_data_file_block, 2); + } else { /* includes : 15 in_iso */ Xorriso_esc_filepath(xorriso, show_path, xorriso->result_line, 0); strcat(xorriso->result_line, "\n"); @@ -3287,8 +3293,10 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, action= Findjob_get_action(job, 0); if(action<0) action= 0; - if(!(flag & 1)) + if(!(flag & 1)) { Xorriso_findi_headline(xorriso, job, 0); + job->last_data_file_block= 0; + } dir_node= (IsoDir *) dir_node_generic; if(dir_node==NULL) { diff --git a/xorriso/iso_tree.c b/xorriso/iso_tree.c index 9ec7e7e3..166cfb15 100644 --- a/xorriso/iso_tree.c +++ b/xorriso/iso_tree.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2014 Thomas Schmitt, + Copyright 2007-2016 Thomas Schmitt, Provided under GPL version 2 or later. @@ -2459,9 +2459,10 @@ int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node, /* @param flag bit0= report_sections : section size rather than total size + bit1= last_data_file_block : looking for highest data file block */ int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path, - IsoNode *node, int flag) + IsoNode *node, uint32_t *last_block, int flag) { int ret, *start_lbas= NULL, *end_lbas= NULL, lba_count, i; off_t size, *section_sizes= NULL; @@ -2477,12 +2478,17 @@ int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path, for(i= 0; i < lba_count; i++) { if(flag & 1) size= section_sizes[i]; - sprintf(xorriso->result_line, - "File data lba: %2d , %8d , %8d , %8.f , ", - i, start_lbas[i], end_lbas[i] + 1 - start_lbas[i], (double) size); - Text_shellsafe(show_path, xorriso->result_line, 1); - strcat(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); + if(flag & 2) { + if(end_lbas[i] > 0 && (uint32_t) end_lbas[i] > *last_block) + *last_block= end_lbas[i]; + } else { + sprintf(xorriso->result_line, + "File data lba: %2d , %8d , %8d , %8.f , ", + i, start_lbas[i], end_lbas[i] + 1 - start_lbas[i], (double) size); + Text_shellsafe(show_path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } } ret= 1; ex:; diff --git a/xorriso/iso_tree.h b/xorriso/iso_tree.h index fb3f0c49..04b353b6 100644 --- a/xorriso/iso_tree.h +++ b/xorriso/iso_tree.h @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2014 Thomas Schmitt, + Copyright 2007-2016 Thomas Schmitt, Provided under GPL version 2 or later. @@ -83,7 +83,7 @@ int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node, int flag); int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path, - IsoNode *node, int flag); + IsoNode *node, uint32_t *last_block, int flag); int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path, IsoNode *node, int flag); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 721c2e77..1d3660f8 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2016.03.22.125444" +#define Xorriso_timestamP "2016.04.25.100906"