diff --git a/libisoburn/isofs_wrap.c b/libisoburn/isofs_wrap.c index c48e8e66..fa68d8ce 100644 --- a/libisoburn/isofs_wrap.c +++ b/libisoburn/isofs_wrap.c @@ -87,6 +87,18 @@ uint32_t iso_read_lsb(const uint8_t *buf, int bytes) } +static +uint64_t iso_read_lsb64(const uint8_t *buf) +{ + int i; + uint64_t ret = 0; + + for (i=0; i < 8; i++) + ret += ((uint64_t) buf[i]) << (i * 8); + return ret; +} + + /* API function. See libisoburn.h */ IsoImage *isoburn_get_attached_image(struct burn_drive *d) @@ -640,6 +652,42 @@ int isoburn_get_img_partition_offset(struct burn_drive *drive, } +/* Try to read partition start and size block number from given GPT entry */ +int isoburn_get_gpt_entry(struct isoburn *o, int partno, + uint64_t *start_lba, uint64_t *size, int flag) +{ + uint32_t part_start, entry_count, entry_size, part_lba, end_lba; + uint8_t *gpt, *part; + + + /* Check for GPT header block */ + gpt = o->target_iso_head + 512; + if(memcmp(gpt, "EFI PART", 8) != 0) + return(0); + if(gpt[8] != 0x00 || gpt[9] != 0x00 || gpt[10] != 0x01 || gpt[11] != 0x00) + return(0); + part_start = iso_read_lsb64(gpt + 72); + entry_count = iso_read_lsb64(gpt + 80); + entry_size = iso_read_lsb64(gpt + 84); + + /* Read partition entry */ + if(partno < 1) + return(0); + if(((uint64_t) partno) > entry_count) + return(0); + if(part_start * 512 + partno * entry_size > 32768) + return(0); + part = o->target_iso_head + part_start * 512 + (partno - 1) * entry_size; + part_lba = iso_read_lsb64(part + 32); + end_lba = iso_read_lsb64(part + 40); + if(end_lba < part_lba) + return(0); + *start_lba = part_lba; + *size = end_lba - part_lba + 1; + return(1); +} + + /* Check for MBR signature and a first partition that starts at a 2k block and ends where the image ends. If not too large or too small, accept its start as partition offset. @@ -649,6 +697,7 @@ static int isoburn_inspect_partition(struct isoburn *o, uint32_t img_size, { uint8_t *mbr, *part, *buf= NULL; uint32_t offst, numsec; + uint64_t gpt_start_lba, gpt_size; struct ecma119_pri_vol_desc *pvm; off_t data_count; int ret; @@ -671,9 +720,20 @@ static int isoburn_inspect_partition(struct isoburn *o, uint32_t img_size, if(part[1] == 0 && part[2] == 0 && part[3] == 0) {ret= 2; goto ex;} /* Zero C/H/S start address */ - /* Does it match the normal ISO image ? */ offst= iso_read_lsb(part + 8, 4); numsec= iso_read_lsb(part + 12, 4); + + /* Is it GPT ? */ + if(part[4] == 0xee && offst == 1) { + ret= isoburn_get_gpt_entry(o, 1, &gpt_start_lba, &gpt_size, 0); + if(ret > 0 && gpt_start_lba < ((uint64_t) 1) << 32 && + gpt_size < ((uint64_t) 1) << 32) { + offst= gpt_start_lba; + numsec= gpt_size; + } + } + + /* Does it match the normal ISO image ? */ if(offst < 64) {ret= 2; goto ex;} /* Zero or unusably small partition start */ if((offst % 4) || (numsec % 4)) diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 7f845330..aa00208c 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2023.06.07.200919" +#define Xorriso_timestamP "2023.07.12.182812"