From 4064a7e0ee264e31c488dde8531a8ef46a1f6a13 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 10 Jan 2019 20:15:44 +0100 Subject: [PATCH] Bug fix: Multi-session emulation spoiled GPT production "GPT partitions ... overlap". Regression towards 1.4.8 --- libisofs/ecma119.c | 5 ++++- libisofs/system_area.c | 47 +++++++++++++++++++++++++++++++++++++++++- libisofs/system_area.h | 17 ++++++++++++++- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 700019c..84303ad 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Mario Danic - * Copyright (c) 2009 - 2018 Thomas Schmitt + * Copyright (c) 2009 - 2019 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -3189,6 +3189,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img) goto target_cleanup; } + /* Delete the filler partitions of GPT and APM so that write_function() + can insert new ones for a possibly different total_size */; + iso_delete_gpt_apm_fillers(target, 0); } /* This was possibly altered by above overwrite buffer production */ diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 9ef222a..7d83c64 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2008 Vreixo Formoso - * Copyright (c) 2010 - 2018 Thomas Schmitt + * Copyright (c) 2010 - 2019 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -1031,6 +1031,7 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array, entry->block_count = block_count; strncpy((char *) entry->name, name, 32); strncpy((char *) entry->type, type, 32); + entry->req_status = 0; ret = iso_register_apm_entry(req_array, apm_req_count, entry, 0); free(entry); return ret; @@ -1076,6 +1077,7 @@ int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array, memcpy(entry->partition_guid, partition_guid, 16); entry->flags = flags; memcpy(entry->name, name, 72); + entry->req_status = 0; ret = iso_register_gpt_entry(req_array, gpt_req_count, entry, 0); free(entry); return ret; @@ -1287,6 +1289,8 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks) gap_name, "ISO9660_data"); if (ret < 0) return ret; + /* Mark as automatically placed filler request */ + t->apm_req[t->apm_req_count - 1]->req_status |= 1; } } @@ -1772,6 +1776,8 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf) gpt_flags, gpt_name); if (ret < 0) return ret; + /* Mark as automatically placed filler request */ + t->gpt_req[t->gpt_req_count - 1]->req_status |= 1; } } /* Merge list of gap partitions with list of already sorted entries */ @@ -3246,3 +3252,42 @@ int partappend_writer_create(Ecma119Image *target) #endif /* Libisofs_appended_partitions_inlinE */ + +void iso_delete_gpt_apm_fillers(Ecma119Image *target, int flag) +{ + int i, widx; + + /* Dispose the requests with req_status bit0 */ + for (i = 0; i < target->gpt_req_count; i++) { + if (target->gpt_req[i]->req_status & 1) { + free(target->gpt_req[i]); + target->gpt_req[i] = NULL; + } + } + /* Densify the request arrays */ + widx = 0; + for (i = 0; i < target->gpt_req_count; i++) { + if (target->gpt_req[i] != NULL) { + target->gpt_req[widx] = target->gpt_req[i]; + widx++; + } + } + target->gpt_req_count = widx; + + /* And again for APM */ + for (i = 0; i < target->apm_req_count; i++) { + if (target->apm_req[i]->req_status & 1) { + free(target->apm_req[i]); + target->apm_req[i] = NULL; + } + } + widx = 0; + for (i = 0; i < target->apm_req_count; i++) { + if (target->apm_req[i] != NULL) { + target->apm_req[widx] = target->apm_req[i]; + widx++; + } + } + target->apm_req_count = widx; +} + diff --git a/libisofs/system_area.h b/libisofs/system_area.h index 4139335..b383584 100644 --- a/libisofs/system_area.h +++ b/libisofs/system_area.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2008 Vreixo Formoso - * Copyright (c) 2012 - 2015 Thomas Schmitt + * Copyright (c) 2012 - 2019 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -155,6 +155,11 @@ struct iso_apm_partition_request { */ uint8_t name[32]; uint8_t type[32]; + + /* Status of the request object itself: + bit0= this is an automatically placed filler partition + */ + uint32_t req_status; }; /* Copies the content of req and registers it in t.apm_req[]. @@ -239,6 +244,11 @@ struct iso_gpt_partition_request { /* Only if read from imported image: Table index of partition (first = 1) */ uint32_t idx; + + /* Status of the request object itself: + bit0= this is an automatically placed filler partition + */ + uint32_t req_status; }; /* Copies the content of req and registers it in t.gpt_req[]. @@ -258,6 +268,11 @@ int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array, uint8_t type_guid[16], uint8_t partition_guid[16], uint64_t flags, uint8_t name[72]); +/* Deletes the partition requests for gap filling in GPT and APM. + Purpose is to get the request list clean again after a multi-session + emulation superblock was created and handed to the application. +*/ +void iso_delete_gpt_apm_fillers(Ecma119Image *target, int flag); /* Internal helper that will be used by system_area.c and make_isohybrid_mbr.c */