New API call iso_write_opts_set_appended_as_gpt()
and marking of appended partitions in GPT if GPT emerges for other reasons.
This commit is contained in:
parent
0819f93f79
commit
527b613607
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -1318,12 +1318,18 @@ ex:
|
||||
static
|
||||
int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
||||
{
|
||||
int res, i;
|
||||
uint8_t *sa;
|
||||
int res, i, ret;
|
||||
uint8_t *sa, *sa_local = NULL;
|
||||
IsoImageWriter *writer;
|
||||
size_t buffer_size = 0, buffer_free = 0, buffer_start_free = 0;
|
||||
|
||||
sa = target->sys_area_as_written;
|
||||
if (target->sys_area_already_written) {
|
||||
LIBISO_ALLOC_MEM(sa_local, uint8_t, 16 * BLOCK_SIZE);
|
||||
sa = sa_local;
|
||||
} else {
|
||||
sa = target->sys_area_as_written;
|
||||
target->sys_area_already_written = 1;
|
||||
}
|
||||
iso_ring_buffer_get_buf_status(target->buffer, &buffer_size,
|
||||
&buffer_start_free);
|
||||
*write_count = 0;
|
||||
@ -1360,9 +1366,16 @@ int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
||||
*write_count = target->bytes_written / BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
goto ex;
|
||||
|
||||
write_error:;
|
||||
return res;
|
||||
ret = res;
|
||||
goto ex;
|
||||
|
||||
ex:
|
||||
LIBISO_FREE_MEM(sa_local);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1483,6 +1496,10 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* >>> need opportunity to read from input ISO image
|
||||
resp. to just mark a partition in the older sessions
|
||||
*/;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL)
|
||||
{ret = ISO_BAD_PARTITION_FILE; goto ex;}
|
||||
@ -1528,8 +1545,10 @@ void issue_ucs2_warning_summary(size_t failures)
|
||||
static
|
||||
void *write_function(void *arg)
|
||||
{
|
||||
int res, first_partition = 1, last_partition = 0, sa_type;
|
||||
int i;
|
||||
int res, i;
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
int first_partition = 1, last_partition = 0, sa_type;
|
||||
#endif
|
||||
IsoImageWriter *writer;
|
||||
|
||||
Ecma119Image *target = (Ecma119Image*)arg;
|
||||
@ -1545,12 +1564,17 @@ void *write_function(void *arg)
|
||||
/* write data for each writer */
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
if (target->gpt_backup_outside &&
|
||||
writer->write_vol_desc == gpt_tail_writer_write_vol_desc)
|
||||
continue;
|
||||
res = writer->write_data(writer);
|
||||
if (res < 0) {
|
||||
goto write_error;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
|
||||
/* Append partition data */
|
||||
sa_type = (target->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type == 0) { /* MBR */
|
||||
@ -1573,6 +1597,19 @@ void *write_function(void *arg)
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_appended_partitions_inlinE */
|
||||
|
||||
if (target->gpt_backup_outside) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
if (writer->write_vol_desc != gpt_tail_writer_write_vol_desc)
|
||||
continue;
|
||||
res = writer->write_data(writer);
|
||||
if (res < 0)
|
||||
goto write_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Transplant checksum buffer from Ecma119Image to IsoImage */
|
||||
transplant_checksum_buffer(target, 0);
|
||||
|
||||
@ -1927,6 +1964,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
target->appended_part_prepad[i] = 0;
|
||||
target->appended_part_start[i] = target->appended_part_size[i] = 0;
|
||||
}
|
||||
target->have_appended_partitions = 0;
|
||||
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++) {
|
||||
target->hfsplus_blessed[i] = src->hfsplus_blessed[i];
|
||||
if (target->hfsplus_blessed[i] != NULL)
|
||||
@ -1946,6 +1984,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
target->gpt_req[i] = NULL;
|
||||
target->gpt_req_count = 0;
|
||||
target->gpt_req_flags = 0;
|
||||
target->gpt_backup_outside = 0;
|
||||
target->gpt_disk_guid_set = 0;
|
||||
target->gpt_part_start = 0;
|
||||
target->gpt_backup_end = 0;
|
||||
@ -1953,11 +1992,23 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
target->gpt_max_entries = 0;
|
||||
target->gpt_is_computed = 0;
|
||||
|
||||
target->sys_area_already_written = 0;
|
||||
|
||||
target->filesrc_start = 0;
|
||||
target->filesrc_blocks = 0;
|
||||
|
||||
target->joliet_ucs2_failures = 0;
|
||||
|
||||
/* If partitions get appended, then the backup GPT cannot be part of
|
||||
the ISO filesystem.
|
||||
*/
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
if (target->opts->appended_partitions[i] != NULL) {
|
||||
target->gpt_backup_outside = 1;
|
||||
target->have_appended_partitions = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Based on those options, create needed writers: iso, joliet...
|
||||
* Each writer inits its structures and stores needed info into
|
||||
@ -1991,6 +2042,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
if (opts->hfsplus || opts->fat) {
|
||||
nwriters+= 2;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
nwriters++; /* Inline Partition Append Writer */
|
||||
|
||||
#endif
|
||||
|
||||
nwriters++; /* GPT backup tail writer */
|
||||
nwriters++; /* Tail padding writer */
|
||||
if ((opts->md5_file_checksums & 1) || opts->md5_session_checksum) {
|
||||
@ -2139,6 +2197,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
|
||||
#endif /* Libisofs_checksums_before_paddinG */
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
ret = partappend_writer_create(target);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
#endif /* Libisofs_appended_partitions_inlinE */
|
||||
|
||||
#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.
|
||||
@ -2204,6 +2270,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
IsoImageWriter *writer = target->writers[i];
|
||||
|
||||
if (target->gpt_backup_outside &&
|
||||
writer->write_vol_desc == gpt_tail_writer_write_vol_desc)
|
||||
continue;
|
||||
|
||||
/* Exposing address of data start to IsoWriteOpts and memorizing
|
||||
this address for all files which have no block address:
|
||||
symbolic links, device files, empty data files.
|
||||
@ -2220,6 +2290,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
if (ret < 0) {
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
target->vol_space_size = target->curblock - opts->ms_block;
|
||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ret = iso_patch_eltoritos(target);
|
||||
@ -2231,6 +2309,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
|
||||
/*
|
||||
* The volume space size is just the size of the last session, in
|
||||
* case of ms images.
|
||||
@ -2243,6 +2323,20 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
#endif /* ! Libisofs_appended_partitions_inlinE */
|
||||
|
||||
if (target->gpt_backup_outside) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
IsoImageWriter *writer = target->writers[i];
|
||||
|
||||
if (writer->write_vol_desc != gpt_tail_writer_write_vol_desc)
|
||||
continue;
|
||||
ret = writer->compute_data_blocks(writer);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* create the ring buffer */
|
||||
if (opts->overwrite != NULL &&
|
||||
opts->fifo_size < 32 + opts->partition_offset) {
|
||||
@ -2732,6 +2826,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->efi_boot_partition = NULL;
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
wopts->appended_partitions[i] = NULL;
|
||||
wopts->appended_as_gpt = 0;
|
||||
wopts->ascii_disc_label[0] = 0;
|
||||
wopts->will_cancel = 0;
|
||||
wopts->allow_dir_id_ext = 0;
|
||||
@ -3445,6 +3540,12 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt)
|
||||
{
|
||||
opts->appended_as_gpt = !!gpt;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
|
||||
{
|
||||
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -480,6 +480,10 @@ struct iso_write_opts {
|
||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||
|
||||
/* If 1: With appended partitions: create protective MBR and mark by GPT
|
||||
*/
|
||||
int appended_as_gpt;
|
||||
|
||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||
*/
|
||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||
@ -756,6 +760,7 @@ struct ecma119_image
|
||||
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
|
||||
int have_appended_partitions;
|
||||
|
||||
/* See IsoImage and libisofs.h */
|
||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||
@ -802,6 +807,9 @@ struct ecma119_image
|
||||
/* bit0= GPT partitions may overlap */
|
||||
int gpt_req_flags;
|
||||
|
||||
/* Whether the eventual backup GPT is not part of the ISO filesystem */
|
||||
int gpt_backup_outside;
|
||||
|
||||
uint32_t efi_boot_part_size;
|
||||
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
|
||||
|
||||
@ -822,6 +830,7 @@ struct ecma119_image
|
||||
write_data() methods of the writers.
|
||||
*/
|
||||
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
|
||||
int sys_area_already_written;
|
||||
|
||||
/* Size of the filesrc_writer area (data file content).
|
||||
This is available before any IsoImageWriter.compute_data_blocks()
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -4014,7 +4014,7 @@ int iso_analyze_gpt_backup(IsoImage *image, IsoDataSource *src, int flag)
|
||||
if (sai->gpt_backup_lba >= ((uint64_t) sai->image_size) * 4 &&
|
||||
(sai->mbr_req_count < 1 ||
|
||||
sai->mbr_req[0]->start_block + sai->mbr_req[0]->block_count
|
||||
!= sai->gpt_backup_lba + 1))
|
||||
> sai->gpt_backup_lba + 1))
|
||||
sprintf(comments + strlen(comments), "Implausible header LBA %.f, ",
|
||||
(double) sai->gpt_backup_lba);
|
||||
iso_block = sai->gpt_backup_lba / 4;
|
||||
@ -4254,6 +4254,26 @@ int iso_analyze_gpt(IsoImage *image, IsoDataSource *src, int flag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check first GPT partition for ISO partition offset */
|
||||
if (sai->partition_offset == 0 && sai->mbr_req_count > 0 &&
|
||||
sai->gpt_req_count > 0) {
|
||||
if (sai->mbr_req[0]->type_byte == 0xee &&
|
||||
sai->mbr_req[0]->start_block == 1) { /* protective MBR */
|
||||
start_block = sai->gpt_req[0]->start_block;
|
||||
block_count = sai->gpt_req[0]->block_count;
|
||||
if (start_block >= 64 && block_count >= 72 &&
|
||||
start_block <= 2048 && start_block % 4 == 0 &&
|
||||
block_count % 4 == 0 &&
|
||||
(start_block + block_count) / 4 == sai->image_size) {
|
||||
|
||||
ret = iso_analyze_partition_offset(image, src, start_block, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||
* Copyright (c) 2009-2014 Thomas Schmitt
|
||||
* Copyright (c) 2009-2015 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
|
||||
@ -2502,6 +2502,24 @@ int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
|
||||
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
||||
uint8_t partition_type, char *image_path, int flag);
|
||||
|
||||
/**
|
||||
* Control whether partitions created by iso_write_opts_set_partition_img()
|
||||
* are to be represented in MBR or as GPT partitions.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param gpt
|
||||
* 0= represent as MBR partition; as GPT only if other GPT partitions
|
||||
* are present
|
||||
* 1= represent as GPT partition and cause protective MBR with a single
|
||||
* partition which covers the whole output data.
|
||||
* This may fail if other settings demand MBR partitions.
|
||||
* @return
|
||||
* ISO_SUCCESS or error
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt);
|
||||
|
||||
/**
|
||||
* Inquire the start address of the file data blocks after having used
|
||||
@ -3730,8 +3748,8 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
|
||||
"If an MBR is detected, with at least one partition entry of non-zero size,", \
|
||||
"then there may be:", \
|
||||
" Partition offset : decimal", \
|
||||
" if not 0 then a second ISO 9660 superblock was found to which MBR", \
|
||||
" partition 1 is pointing.", \
|
||||
" if not 0 then a second ISO 9660 superblock was found to which", \
|
||||
" MBR partition 1 or GPT partition 1 is pointing.", \
|
||||
" MBR heads per cyl : decimal", \
|
||||
" conversion factor between MBR C/H/S address and LBA. 0=inconsistent.", \
|
||||
" MBR secs per head : decimal", \
|
||||
|
@ -290,6 +290,7 @@ iso_write_opts_set_allow_longer_paths;
|
||||
iso_write_opts_set_allow_lowercase;
|
||||
iso_write_opts_set_always_gmt;
|
||||
iso_write_opts_set_appendable;
|
||||
iso_write_opts_set_appended_as_gpt;
|
||||
iso_write_opts_set_default_dir_mode;
|
||||
iso_write_opts_set_default_file_mode;
|
||||
iso_write_opts_set_default_gid;
|
||||
|
@ -1,3 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2008 - 2015 Thomas Schmitt
|
||||
* with special credits to H. Peter Anvin for isohybrid
|
||||
* and to Matthew Garrett for isohybrid with GPT and APM
|
||||
*
|
||||
* 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
|
||||
* or later as published by the Free Software Foundation.
|
||||
* See COPYING file for details.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -559,6 +569,7 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
||||
|
||||
/*
|
||||
* @param flag bit0= make own random MBR Id from current time
|
||||
* bit1= create protective MBR as of UEFI/GPT specs
|
||||
*/
|
||||
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
|
||||
int part_offset, int part_number, int fs_type,
|
||||
@ -574,6 +585,11 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
if (flag & 2) {
|
||||
part_number = 1;
|
||||
part_offset = 1;
|
||||
}
|
||||
|
||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||
|
||||
boot_lba = t->bootsrc[0]->sections[0].block;
|
||||
@ -639,14 +655,17 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
|
||||
wpt+= 16;
|
||||
continue;
|
||||
}
|
||||
/* write byte 0x80
|
||||
/* write byte 0x80 if bootable
|
||||
write LBA_to_CHS(partition_offset)
|
||||
write byte filesystem_type
|
||||
write LBA_to_CHS(image_size-1)
|
||||
write dword partition_offset
|
||||
write dword image_size
|
||||
*/
|
||||
lsb_to_buf(&wpt, 0x80, 8, 0);
|
||||
if (flag & 2)
|
||||
lsb_to_buf(&wpt, 0x00, 8, 0);
|
||||
else
|
||||
lsb_to_buf(&wpt, 0x80, 8, 0);
|
||||
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
|
||||
lsb_to_buf(&wpt, fs_type, 8, 0);
|
||||
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Vreixo Formoso
|
||||
* Copyright (c) 2010 - 2014 Thomas Schmitt
|
||||
* Copyright (c) 2010 - 2015 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
|
||||
@ -128,6 +128,7 @@ static uint32_t compute_partition_size(char *disk_path, uint32_t *size,
|
||||
}
|
||||
|
||||
/* Compute size and position of appended partitions.
|
||||
@param flag bit0= Partitions inside ISO : update t->curblock
|
||||
*/
|
||||
int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
{
|
||||
@ -170,6 +171,8 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
t->appended_part_size[i] = size;
|
||||
pos += add_pos + size;
|
||||
t->total_size += (add_pos + size) * 2048;
|
||||
if (flag & 1)
|
||||
t->curblock = pos;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -312,6 +315,7 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
|
||||
|
||||
|
||||
/* @param flag bit0= zeroize partitions entries 2, 3, 4
|
||||
bit0= UEFI protective MBR: start LBA = 1
|
||||
*/
|
||||
static
|
||||
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||
@ -326,6 +330,11 @@ int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||
iso_compute_cyl_head_sec((uint64_t) img_blocks, hpc, sph,
|
||||
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||
if (flag & 2) {
|
||||
start_lba = 1;
|
||||
start_sec = 2;
|
||||
start_head = start_cyl = 0;
|
||||
}
|
||||
wpt = buf + 446;
|
||||
|
||||
/* Let pass only legal bootability values */
|
||||
@ -1552,7 +1561,11 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
||||
}
|
||||
} else if (part_end < goal) {
|
||||
memset(gpt_name, 0, 72);
|
||||
sprintf((char *) gpt_name, "Gap%d", gap_counter);
|
||||
if (goal == t->vol_space_size * (uint64_t) 4 &&
|
||||
part_end == t->opts->partition_offset * (uint64_t) 4)
|
||||
sprintf((char *) gpt_name, "ISO9660");
|
||||
else
|
||||
sprintf((char *) gpt_name, "Gap%d", gap_counter);
|
||||
iso_ascii_utf_16le(gpt_name);
|
||||
gap_counter++;
|
||||
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
|
||||
@ -1577,6 +1590,9 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
||||
end_lba = req->start_block + req->block_count;
|
||||
backup_end_lba = ((uint64_t) t->gpt_backup_end - t->gpt_backup_size) *
|
||||
4;
|
||||
if (req->start_block == t->opts->partition_offset * ((uint64_t) 4) &&
|
||||
req->block_count == ((uint64_t) 4) * 0xffffffff)
|
||||
end_lba = t->vol_space_size * 4;
|
||||
if (end_lba > backup_end_lba)
|
||||
end_lba = backup_end_lba;
|
||||
end_lba = end_lba - 1;
|
||||
@ -1601,9 +1617,10 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
|
||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
{
|
||||
int ret, int_img_blocks, sa_type, i, will_append = 0, do_isohybrid = 0;
|
||||
int first_partition = 1, last_partition = 4, apm_flag, part_type;
|
||||
int gpt_count = 0, gpt_idx[128], apm_count = 0;
|
||||
uint32_t img_blocks;
|
||||
int first_partition = 1, last_partition = 4, apm_flag, part_type = 0;
|
||||
int gpt_count = 0, gpt_idx[128], apm_count = 0, no_boot_mbr = 0;
|
||||
int offset_flag = 0;
|
||||
uint32_t img_blocks, gpt_blocks, mbrp1_blocks;
|
||||
uint64_t blk;
|
||||
uint8_t *wpt;
|
||||
|
||||
@ -1695,7 +1712,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
}
|
||||
if (t->mbr_req_count > 0 && sa_type != 0)
|
||||
return ISO_NON_MBR_SYS_AREA;
|
||||
ret = iso_write_gpt(t, img_blocks, buf);
|
||||
|
||||
if (t->gpt_backup_outside)
|
||||
gpt_blocks = t->total_size / 2048;
|
||||
else
|
||||
gpt_blocks = img_blocks;
|
||||
ret = iso_write_gpt(t, gpt_blocks, buf);
|
||||
if (ret < 0) {
|
||||
iso_msg_submit(t->image->id, ret, 0, "Cannot set up GPT");
|
||||
return ret;
|
||||
@ -1724,12 +1746,19 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
else
|
||||
part_type = 0x17;
|
||||
|
||||
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
|
||||
part_type = 0xee;
|
||||
img_blocks = gpt_blocks;
|
||||
no_boot_mbr = 2;
|
||||
}
|
||||
|
||||
/* >>> ??? Why is partition_offset 0 here ?
|
||||
It gets adjusted later by iso_offset_partition_start()
|
||||
Would it harm to give the real offset here ?
|
||||
*/;
|
||||
|
||||
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, part_type, buf, 1);
|
||||
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, part_type, buf,
|
||||
1 | no_boot_mbr);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
} else if (sa_type == 1) {
|
||||
@ -1773,9 +1802,17 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
With t->mbr_req_count > 0 this has already been done,
|
||||
*/
|
||||
img_blocks = t->curblock; /* value might be altered */
|
||||
ret = iso_offset_partition_start(img_blocks, t->opts->partition_offset,
|
||||
if (part_type == 0xee) {
|
||||
mbrp1_blocks = t->total_size / 2048;
|
||||
offset_flag |= 2 | 1; /* protective MBR, no other partitions */
|
||||
} else {
|
||||
mbrp1_blocks = img_blocks;
|
||||
}
|
||||
ret = iso_offset_partition_start(mbrp1_blocks,
|
||||
t->opts->partition_offset,
|
||||
t->partition_secs_per_head,
|
||||
t->partition_heads_per_cyl, buf, 0);
|
||||
t->partition_heads_per_cyl, buf,
|
||||
offset_flag);
|
||||
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
@ -1783,27 +1820,29 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
/* This eventually overwrites the non-mbr_req partition table entries
|
||||
made so far. Overwriting those from t->mbr_req is not allowed.
|
||||
*/
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||
if (t->opts->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
if (i < t->mbr_req_count)
|
||||
return ISO_BOOT_MBR_COLLISION;
|
||||
if (sa_type == 3) {
|
||||
ret = write_sun_partition_entry(i + 1,
|
||||
if (sa_type == 3 || !t->opts->appended_as_gpt) {
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||
if (t->opts->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
if (i < t->mbr_req_count)
|
||||
return ISO_BOOT_MBR_COLLISION;
|
||||
if (sa_type == 3) {
|
||||
ret = write_sun_partition_entry(i + 1,
|
||||
t->opts->appended_partitions,
|
||||
t->appended_part_start, t->appended_part_size,
|
||||
ISO_SUN_CYL_SIZE,
|
||||
buf, t->opts->appended_partitions[i][0] == 0);
|
||||
} else {
|
||||
ret = write_mbr_partition_entry(i + 1,
|
||||
} else {
|
||||
ret = write_mbr_partition_entry(i + 1,
|
||||
t->opts->appended_part_types[i],
|
||||
(uint64_t) t->appended_part_start[i],
|
||||
(uint64_t) t->appended_part_size[i],
|
||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||
buf, 0);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
|
||||
@ -1860,10 +1899,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 backup GPT */;
|
||||
ret = precompute_gpt(t);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
if (!t->gpt_backup_outside) {
|
||||
/* Take into account the backup GPT */;
|
||||
ret = precompute_gpt(t);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
img_blocks = t->curblock + t->opts->tail_blocks + t->gpt_backup_size;
|
||||
imgsize = ((off_t) img_blocks) * (off_t) 2048;
|
||||
@ -2137,6 +2178,53 @@ fallback:;
|
||||
|
||||
}
|
||||
|
||||
int assess_appended_gpt(Ecma119Image *t, int flag)
|
||||
{
|
||||
static uint8_t basic_data_uuid[16] = {
|
||||
0xa2, 0xa0, 0xd0, 0xeb, 0xe5, 0xb9, 0x33, 0x44,
|
||||
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
|
||||
};
|
||||
static uint8_t efi_sys_uuid[16] = {
|
||||
0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
|
||||
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
|
||||
};
|
||||
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;
|
||||
uint8_t gpt_name[72], *type_uuid;
|
||||
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
if (!t->gpt_backup_outside)
|
||||
return 2;
|
||||
#endif
|
||||
|
||||
/* Represent in GPT only if other GPT partitions are already registered
|
||||
or if appended partitions are explicitely desired for GPT-only.
|
||||
*/
|
||||
if (t->gpt_req_count == 0 &&
|
||||
!(t->have_appended_partitions && t->opts->appended_as_gpt))
|
||||
return 2;
|
||||
|
||||
/* Represent appended partitions */
|
||||
for (i = 0; i <= 3; i++) {
|
||||
if (t->opts->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
memset(gpt_name, 0, 72);
|
||||
sprintf((char *) gpt_name, "Appended%d", i + 1);
|
||||
iso_ascii_utf_16le(gpt_name);
|
||||
if (t->opts->appended_part_types[i] == 0xef)
|
||||
type_uuid = efi_sys_uuid;
|
||||
else
|
||||
type_uuid = basic_data_uuid;
|
||||
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
|
||||
((uint64_t) t->appended_part_start[i]) * 4,
|
||||
((uint64_t) t->appended_part_size[i]) * 4,
|
||||
type_uuid, zero_uuid,
|
||||
(uint64_t) 0, gpt_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* Probably already called by tail_writer_compute_data_blocks via
|
||||
iso_align_isohybrid
|
||||
@ -2181,6 +2269,9 @@ 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 */
|
||||
|
||||
@ -2262,7 +2353,7 @@ static int precompute_gpt(Ecma119Image *t)
|
||||
}
|
||||
|
||||
|
||||
static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
int ret;
|
||||
@ -2276,15 +2367,22 @@ static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
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;
|
||||
|
||||
if (t->gpt_backup_outside) {
|
||||
t->total_size += t->gpt_backup_size * 2048;
|
||||
/* The ISO block number after the backup GPT header */
|
||||
t->gpt_backup_end = t->total_size / 2048;
|
||||
} else {
|
||||
t->curblock += t->gpt_backup_size;
|
||||
/* The ISO block number after the backup GPT header */
|
||||
t->gpt_backup_end = t->curblock;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int gpt_tail_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
int gpt_tail_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -2348,6 +2446,12 @@ tampered_head:;
|
||||
free(backup_buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!t->gpt_backup_outside) {
|
||||
|
||||
/* >>> Why isn't t->curblock updated ? */;
|
||||
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
|
||||
write_zeros:;
|
||||
@ -2560,3 +2664,87 @@ int partprepend_writer_create(Ecma119Image *target)
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
/* ----------------- Inline Partition Append Writer ------------------ */
|
||||
|
||||
|
||||
static int partappend_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_compute_append_partitions(writer->target, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int partappend_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int partappend_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *target;
|
||||
int res, first_partition = 1, last_partition = 0, sa_type;
|
||||
int i;
|
||||
|
||||
target = writer->target;
|
||||
|
||||
/* Append partition data */
|
||||
sa_type = (target->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type == 0) { /* MBR */
|
||||
first_partition = 1;
|
||||
last_partition = 4;
|
||||
} else if (sa_type == 3) { /* SUN Disk Label */
|
||||
first_partition = 2;
|
||||
last_partition = 8;
|
||||
}
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||
if (target->opts->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
if (target->opts->appended_partitions[i][0] == 0)
|
||||
continue;
|
||||
res = iso_write_partition_file(target,
|
||||
target->opts->appended_partitions[i],
|
||||
target->appended_part_prepad[i],
|
||||
target->appended_part_size[i], 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
target->curblock += target->appended_part_size[i];
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int partappend_writer_free_data(IsoImageWriter *writer)
|
||||
{
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int partappend_writer_create(Ecma119Image *target)
|
||||
{
|
||||
IsoImageWriter *writer;
|
||||
|
||||
writer = calloc(1, sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
writer->compute_data_blocks = partappend_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = partappend_writer_write_vol_desc;
|
||||
writer->write_data = partappend_writer_write_data;
|
||||
writer->free_data = partappend_writer_free_data;
|
||||
writer->data = NULL;
|
||||
writer->target = target;
|
||||
|
||||
/* add this writer to image */
|
||||
target->writers[target->nwriters++] = writer;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_appended_partitions_inlinE */
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Vreixo Formoso
|
||||
* Copyright (c) 2012 Thomas Schmitt
|
||||
* Copyright (c) 2012 - 2015 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
|
||||
@ -281,10 +281,20 @@ struct iso_sun_disk_label_entry {
|
||||
*/
|
||||
int partprepend_writer_create(Ecma119Image *target);
|
||||
|
||||
/* Creates the Inline Partition Append Writer
|
||||
*/
|
||||
int partappend_writer_create(Ecma119Image *target);
|
||||
|
||||
/* Creates the GPT backup tail writer.
|
||||
*/
|
||||
int gpt_tail_writer_create(Ecma119Image *target);
|
||||
|
||||
/* Not for execution but only to identify the writer by
|
||||
( writer->write_vol_desc == gpt_tail_writer_write_vol_desc )
|
||||
*/
|
||||
int gpt_tail_writer_write_vol_desc(IsoImageWriter *writer);
|
||||
|
||||
|
||||
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
|
||||
void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
||||
|
||||
@ -301,4 +311,10 @@ void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
||||
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
|
||||
#define Libisofs_grub2_sparc_patch_size_poS 0x230
|
||||
|
||||
|
||||
/* >>> It is unclear whether there is a use case for appended partitions
|
||||
inside the ISO filesystem range.
|
||||
# define Libisofs_appended_partitions_inlinE yes
|
||||
*/
|
||||
|
||||
#endif /* SYSTEM_AREA_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user