From 0ebc8fe18677a3226aec556cf71424e77fae4a0c Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 13 Jun 2012 13:31:37 +0200 Subject: [PATCH] Provisorily moved tail writer after checksum writer and accounted for size of backup GPT in cylinder alignment of tail writer. --- libisofs/ecma119.c | 18 ++++++++++- libisofs/ecma119.h | 2 ++ libisofs/make_isohybrid_mbr.c | 2 +- libisofs/system_area.c | 60 +++++++++++++++++++++++------------ 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 7f94b3b..e018199 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -1920,7 +1920,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) target->gpt_req[i] = NULL; target->gpt_part_start = 0; target->gpt_backup_end = 0; + target->gpt_backup_size = 0; target->gpt_max_entries = 0; + target->gpt_is_computed = 0; target->filesrc_blocks = 0; @@ -2083,19 +2085,33 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) #endif /* ! Libisofs_gpt_writer_lasT */ - /* >>> Should not the checksum writer come before the zero writer ? */ +/* >>> Should not the checksum writer come before the zero writer ? +*/ +#define Libisofs_checksums_before_paddinG yes +#ifndef Libisofs_checksums_before_paddinG + /* >>> ??? Why is this important ? */ /* IMPORTANT: This must be the last writer before the checksum writer */ ret = zero_writer_create(target, target->tail_blocks, 1); if (ret < 0) goto target_cleanup; +#endif /* !Libisofs_checksums_before_paddinG */ + if ((target->md5_file_checksums & 1) || target->md5_session_checksum) { ret = checksum_writer_create(target); if (ret < 0) goto target_cleanup; } +#ifdef Libisofs_checksums_before_paddinG + + ret = zero_writer_create(target, target->tail_blocks, 1); + if (ret < 0) + goto target_cleanup; + +#endif /* Libisofs_checksums_before_paddinG */ + #ifdef Libisofs_gpt_writer_lasT /* This writer shall be the last one in the list, because it protects the image on media which are seen as GPT partitioned. diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index 07f761b..12c47c3 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -856,7 +856,9 @@ struct ecma119_image uint32_t gpt_part_start; /* The ISO block number after the backup GPT header , block size 2048 */ uint32_t gpt_backup_end; + uint32_t gpt_backup_size; uint32_t gpt_max_entries; + int gpt_is_computed; /* Message from write_head_part1()/iso_write_system_area() to the write_data() methods of the writers. diff --git a/libisofs/make_isohybrid_mbr.c b/libisofs/make_isohybrid_mbr.c index 64434e4..454d3ca 100644 --- a/libisofs/make_isohybrid_mbr.c +++ b/libisofs/make_isohybrid_mbr.c @@ -405,7 +405,7 @@ static int assess_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128], iso_msgs_submit(0, "Too many entries desired for Apple Partition Map. (max 6)", 0, "FAILURE", 0); - return ISO_ISOLINUX_CANT_PATCH; + return ISO_BOOT_TOO_MANY_APM; } return ISO_SUCCESS; } diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 7f59b59..d39930b 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -58,6 +58,8 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t, int part_offset, int part_number, int fs_type, uint8_t *buf, int flag); +static int precompute_gpt(Ecma119Image *t); + /* * @param flag bit0= img_blocks is start address rather than end address: @@ -1533,9 +1535,12 @@ int iso_align_isohybrid(Ecma119Image *t, int flag) {ret = ISO_SUCCESS; goto ex;} always_align = (t->system_area_options >> 8) & 3; - /* >>> Take into account the other stuff: TAIL GPTB */; + /* Take into account the backup GPT */; + ret = precompute_gpt(t); + if (ret < 0) + goto ex; - img_blocks = t->curblock + t->tail_blocks; + img_blocks = t->curblock + t->tail_blocks + t->gpt_backup_size; imgsize = ((off_t) img_blocks) * (off_t) 2048; if (((t->system_area_options & 3) || always_align) && (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head @@ -1794,16 +1799,14 @@ void iso_random_8byte(Ecma119Image *t, uint8_t result[8]) } -static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer) +/* Probably already called by tail writer */ +static int precompute_gpt(Ecma119Image *t) { - Ecma119Image *t; - uint32_t gpt_part_start, gpt_size; + uint32_t gpt_part_start; int ret; - if (writer == NULL) { - return ISO_ASSERT_FAILURE; - } - t = writer->target; + /* Avoid repetition by gpt_tail_writer_compute_data_blocks */ + t->gpt_is_computed = 1; /* Rectify APM requests early in order to learn the size of GPT. iso_write_apm() relies on this being already done here. @@ -1877,10 +1880,27 @@ static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer) /* Necessary number of 2K blocks */ t->gpt_max_entries = (64 - t->gpt_part_start) * 4; - gpt_size = (t->gpt_max_entries / 4 + 1) * 512; - t->curblock += gpt_size / 2048; - if (gpt_size % 2048) - t->curblock++; + t->gpt_backup_size = ((t->gpt_max_entries / 4 + 1) * 512 + 2047) / 2048; + + return ISO_SUCCESS; +} + + +static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer) +{ + Ecma119Image *t; + int ret; + + if (writer == NULL) + return ISO_ASSERT_FAILURE; + t = writer->target; + + if (! t->gpt_is_computed) { + ret = precompute_gpt(t); + if (ret < 0) + return ret; + } + t->curblock += t->gpt_backup_size; /* The ISO block number after the backup GPT header */ t->gpt_backup_end = t->curblock; @@ -1899,7 +1919,7 @@ static int gpt_tail_writer_write_data(IsoImageWriter *writer) Ecma119Image *t; uint8_t *head, *new_head, *entries; uint8_t *backup_buf = NULL; - uint32_t gpt_size, crc, i; + uint32_t crc, i; uint64_t part_start; int ret; @@ -1907,12 +1927,10 @@ static int gpt_tail_writer_write_data(IsoImageWriter *writer) if (t->gpt_backup_end == 0 || t->gpt_max_entries == 0) return ISO_SUCCESS; /* No backup GPT area reserved by compute_data() */ - gpt_size = (t->gpt_max_entries / 4 + 1) * 512; - gpt_size = gpt_size / 2048 + !!(gpt_size % 2048); - backup_buf = calloc(1, gpt_size * 2048); + backup_buf = calloc(1, t->gpt_backup_size * 2048); if (backup_buf == NULL) return ISO_OUT_OF_MEM; - memset(backup_buf, 0, gpt_size * 2048); + memset(backup_buf, 0, t->gpt_backup_size * 2048); /* Check whether GPT header block came through */ head = t->sys_area_as_written + 512; @@ -1929,7 +1947,7 @@ tampered_head:; goto tampered_head; /* Patch memorized header block */ - new_head = backup_buf + gpt_size * 2048 - 512; + new_head = backup_buf + t->gpt_backup_size * 2048 - 512; memcpy(new_head, head, 512); /* Exchange "Location of this header" and "Location of header backup" */ memcpy(new_head + 24, head + 32, 8); @@ -1950,14 +1968,14 @@ tampered_head:; memcpy(new_head - t->gpt_max_entries * 128, entries, t->gpt_max_entries * 128); - ret = iso_write(t, backup_buf, gpt_size * 2048); + ret = iso_write(t, backup_buf, t->gpt_backup_size * 2048); free(backup_buf); if (ret < 0) return ret; return ISO_SUCCESS; write_zeros:; - ret = iso_write(t, backup_buf, gpt_size * 2048); + ret = iso_write(t, backup_buf, t->gpt_backup_size * 2048); free(backup_buf); if (ret < 0) return ret;