Bug fix: Appended APM partitions without HFS+ production had start and size 1

This commit is contained in:
Thomas Schmitt 2020-11-15 15:23:03 +01:00
parent 29cc5c8d31
commit cece6fb371
4 changed files with 37 additions and 11 deletions

View File

@ -2705,6 +2705,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->hfsp_cat_node_size = 0;
target->hfsp_iso_block_fac = 0;
target->hfsp_collision_count = 0;
iso_setup_hfsplus_block_size(target);
target->apm_req_count = 0;
target->apm_req_flags = 0;
for (i = 0; i < ISO_APM_ENTRIES_MAX; i++)

View File

@ -1579,6 +1579,14 @@ int mangle_leafs(Ecma119Image *target, int flag)
return ISO_SUCCESS;
}
void iso_setup_hfsplus_block_size(Ecma119Image *target)
{
if (target->opts->hfsp_block_size == 0)
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
}
int hfsplus_writer_create(Ecma119Image *target)
{
int ret;
@ -1599,10 +1607,7 @@ int hfsplus_writer_create(Ecma119Image *target)
make_hfsplus_decompose_pages();
make_hfsplus_class_pages();
if (target->opts->hfsp_block_size == 0)
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
iso_setup_hfsplus_block_size(target);
cat_node_size = target->hfsp_cat_node_size;
writer->compute_data_blocks = hfsplus_writer_compute_data_blocks;

View File

@ -197,5 +197,6 @@ extern const uint16_t hfsplus_casefold[];
int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
uint16_t **result, uint32_t *result_len, uint16_t **cmp_name);
void iso_setup_hfsplus_block_size(Ecma119Image *target);
#endif /* LIBISO_HFSPLUS_H */

View File

@ -1403,8 +1403,13 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
/* Adjust last partition to img_size. This size was not known when the
number of APM partitions was determined.
*/
t->apm_req[t->apm_req_count - 1]->block_count =
img_blocks * block_fac - t->apm_req[t->apm_req_count - 1]->start_block;
if (img_blocks * block_fac <
t->apm_req[t->apm_req_count - 1]->start_block)
t->apm_req[t->apm_req_count - 1]->block_count = 0;
else
t->apm_req[t->apm_req_count - 1]->block_count =
img_blocks * block_fac -
t->apm_req[t->apm_req_count - 1]->start_block;
/* If it is still empty, remove it */
if(t->apm_req[t->apm_req_count - 1]->block_count == 0) {
free(t->apm_req[t->apm_req_count - 1]);
@ -2158,7 +2163,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* This possibly overwrites the non-mbr_req partition table entries
made so far. Overwriting those from t->mbr_req is not allowed.
*/
if (sa_type == 3 || !t->opts->appended_as_gpt) {
if (sa_type == 3 ||
!(t->opts->appended_as_gpt || t->opts->appended_as_apm)) {
for (i = first_partition - 1; i <= last_partition - 1; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
@ -2640,9 +2646,14 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
};
static uint8_t hfs_plus_uuid[16] = {
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
};
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt = 0;
uint8_t gpt_name[72], *type_uuid;
char apm_type[33];
#ifndef Libisofs_appended_partitions_inlinE
if (!t->gpt_backup_outside)
@ -2666,10 +2677,16 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
if (do_apm) {
memset(gpt_name, 0, 32);
sprintf((char *) gpt_name, "Appended%d", i + 1);
strcpy(apm_type, "Data");
if (t->opts->appended_part_gpt_flags[i] & 1) {
if (memcmp(t->opts->appended_part_type_guids[i], hfs_plus_uuid,
16) == 0)
strcpy(apm_type, "Apple_HFS");
}
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->appended_part_start[i] * t->hfsp_iso_block_fac,
t->appended_part_size[i] * t->hfsp_iso_block_fac,
(char *) gpt_name, "Data");
(char *) gpt_name, apm_type);
if (ret < 0)
return ret;
}
@ -2752,6 +2769,11 @@ static int precompute_gpt(Ecma119Image *t)
do not adjust final APM partition size */
}
/* Assess impact of appended partitions on GPT */
ret = assess_appended_gpt(t, 0);
if (ret < 0)
return ret;
/* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here.
So perform even if no GPT is required.
@ -2760,9 +2782,6 @@ static int precompute_gpt(Ecma119Image *t)
if (ret < 0)
return ret;
/* Assess impact of appended partitions on GPT */
ret = assess_appended_gpt(t, 0);
#ifdef NIX
/* Disabled */