New command -extract_boot_images

This commit is contained in:
2020-12-05 09:53:59 +01:00
parent e97cd48ee0
commit 47be075c45
16 changed files with 647 additions and 131 deletions

View File

@ -2332,7 +2332,8 @@ ex:;
}
/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages
/* @param flag bit0= ignore node and img_path, operate on whole medium
bit1= for Xorriso_check_interval(): no pacifier messages
*/
int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
char *img_path, char *disk_path,
@ -2341,6 +2342,8 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
{
int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16;
int lba, count, blocks, quality, spot, bad_extract= 0;
int data_to_skip= 0;
uint32_t indev_blocks;
off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr;
off_t new_file_base_bytes, upto_file_bytes, start_byte= 0;
off_t *section_sizes = NULL;
@ -2348,25 +2351,33 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
struct CheckmediajoB *job= NULL;
upto_file_bytes= img_offset + bytes;
data_to_skip= img_offset % (off_t) 2048;
/* >>> make Xorriso_check_interval() ready for copying in byte granularity */
if(img_offset % (off_t) 2048) {
sprintf(xorriso->info_text,
"Image address offset is not a multiple of 2048");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
&section_sizes, &size, 0);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, "File object ");
Text_shellsafe(img_path, xorriso->info_text, 1);
strcat(xorriso->info_text,
" is currently not a data file from the loaded image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
if(flag & 1) {
lba_count= 1;
Xorriso_alloc_meM(start_lbas, int, 1);
Xorriso_alloc_meM(end_lbas, int, 1);
Xorriso_alloc_meM(section_sizes, off_t, 1);
start_lbas[0]= 0;
ret= Xorriso_obtain_indev_readsize(xorriso, &indev_blocks, 0);
if(ret > 0)
end_lbas[0]= indev_blocks - 1;
else
end_lbas[0]= 0x7ffffffe;
size= ((off_t) end_lbas[0]) * 2048;
section_sizes[0]= size;
} else {
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
&section_sizes, &size, 0);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, "File object ");
Text_shellsafe(img_path, xorriso->info_text, 1);
strcat(xorriso->info_text,
" is currently not a data file from the loaded image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
}
if(img_offset + bytes < size && bytes > 0)
size= img_offset + bytes;
@ -2409,13 +2420,14 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
file_base_bytes= img_offset;
}
/* Eventually omit surplus blocks */
/* Omit surplus blocks */
if(new_file_base_bytes > upto_file_bytes)
count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048;
/* Adjust job */
job->data_to_offset= file_processed_bytes - img_adr + disk_offset;
job->data_to_limit= size - file_base_bytes;
job->data_to_skip= data_to_skip;
data_to_skip= 0;
file_processed_bytes+= ((off_t) count) * (off_t) 2048;
ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
0, (flag & 2));
@ -2471,6 +2483,103 @@ ex:;
}
int Xorriso_extract_boot_images(struct XorrisO *xorriso, char *disk_dir_path,
int flag)
{
int ret, img_count= 0, i, was_problem= 0;
char **imgs= NULL, *eff_path= NULL, *cpt, *eff_namept;
struct stat stbuf;
off_t byte_offset, byte_size;
Xorriso_alloc_meM(eff_path, char, SfileadrL);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_dir_path,
eff_path, 2 | 4);
if(ret <= 0)
goto ex;
if(strlen(eff_path) > SfileadrL - 80) {
sprintf(xorriso->info_text,
"-extract_boot_images: disk_path is too long (%lu)\n",
(unsigned long int) strlen(eff_path));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= stat(eff_path, &stbuf);
if(ret == 0) {
if(!S_ISDIR(stbuf.st_mode)) {
sprintf(xorriso->info_text,
"-extract_boot_images: disk_path is not a directory : ");
Text_shellsafe(eff_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
ret= mkdir(eff_path, 0777);
if(ret == -1) {
sprintf(xorriso->info_text,
"-extract_boot_images: cannot create directory : ");
Text_shellsafe(eff_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
}
strcat(eff_path, "/");
eff_namept= eff_path + strlen(eff_path);
ret= Xorriso_list_boot_images(xorriso, &imgs, &img_count, 0);
if(ret <= 0)
goto ex;
/* Interpret list and create files */
for(i= 0; i < img_count; i++) {
ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
if(ret < 0)
{ret= 0; goto ex;}
cpt= strchr(imgs[i], '/');
if(cpt == NULL)
continue;
*cpt= 0;
cpt+= 2;
ret= Sfile_text_to_off_t(cpt, &byte_offset, 0);
if(ret <= 0)
continue;
cpt+= ret;
if(*cpt == 0)
continue;
cpt++;
ret= Sfile_text_to_off_t(cpt, &byte_size, 0);
if(ret <= 0)
continue;
strcpy(eff_namept, imgs[i]);
sprintf(xorriso->info_text, "%s : offset=%.f size=%.f\n",
eff_path, (double) byte_offset, (double) byte_size);
Xorriso_info(xorriso, 0);
ret= stat(eff_path, &stbuf);
if(ret != -1) {
sprintf(xorriso->info_text,
"-extract_boot_images: File already exists on disk: ");
Text_shellsafe(eff_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
continue;
}
ret= Xorriso_read_file_data(xorriso, NULL, NULL, eff_path,
byte_offset, (off_t) 0, byte_size, 1);
if(ret <= 0)
was_problem= 1;
}
ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
if(ret < 0 || was_problem)
{ret= 0; goto ex;}
ret= 1;
ex:;
Xorriso_free_meM(eff_path);
Xorriso_list_boot_images(xorriso, &imgs, &img_count, 1 << 15);
return(ret);
}
/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL.
@param path is used as address if node is NULL.
@param flag bit0= do not report to result but only indicate outcome