New API calls so_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp()

This commit is contained in:
Thomas Schmitt 2012-06-12 13:24:50 +02:00
parent 0897896713
commit 6a3273dc72
7 changed files with 351 additions and 34 deletions

View File

@ -116,6 +116,10 @@ void ecma119_image_free(Ecma119Image *t)
free(t->writers);
if (t->partition_root != NULL)
ecma119_node_free(t->partition_root);
if (t->prep_partition != NULL)
free(t->prep_partition);
if (t->efi_boot_partition != NULL)
free(t->efi_boot_partition);
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (t->appended_partitions[i] != NULL)
free(t->appended_partitions[i]);
@ -1403,8 +1407,8 @@ static int finish_libjte(Ecma119Image *target)
}
static int write_mbr_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag)
int iso_write_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag)
{
FILE *fp = NULL;
uint32_t i;
@ -1486,7 +1490,7 @@ void *write_function(void *arg)
continue;
if (target->appended_partitions[i][0] == 0)
continue;
res = write_mbr_partition_file(target, target->appended_partitions[i],
res = iso_write_partition_file(target, target->appended_partitions[i],
target->appended_part_prepad[i],
target->appended_part_size[i], 0);
if (res < 0)
@ -1777,6 +1781,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (opts->appended_partitions[i] != NULL)
return ISO_NON_MBR_SYS_AREA;
if (sa_type != 0 && opts->prep_partition != NULL)
return ISO_NON_MBR_SYS_AREA;
target->system_area_data = NULL;
if (system_area != NULL) {
@ -1873,6 +1879,20 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->wthread_is_running = 0;
target->prep_partition = NULL;
if (opts->prep_partition != NULL) {
target->prep_partition = strdup(opts->prep_partition);
if (target->prep_partition == NULL)
return ISO_OUT_OF_MEM;
}
target->prep_part_size = 0;
target->efi_boot_partition = NULL;
if (opts->efi_boot_partition != NULL) {
target->efi_boot_partition = strdup(opts->efi_boot_partition);
if (target->efi_boot_partition == NULL)
return ISO_OUT_OF_MEM;
}
target->efi_boot_part_size = 0;
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
target->appended_partitions[i] = NULL;
if (opts->appended_partitions[i] != NULL) {
@ -1930,12 +1950,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
if (target->joliet) {
nwriters++;
}
if (target->hfsplus || target->fat) {
nwriters+= 2;
}
if (target->iso1999) {
nwriters++;
}
nwriters++; /* Partition Prepend writer */
if (target->hfsplus || target->fat) {
nwriters+= 2;
}
nwriters++; /* GPT backup tail writer */
nwriters++; /* Tail padding writer */
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
@ -2010,6 +2031,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
goto target_cleanup;
}
/* The writer for MBR and GPT partitions outside iso_file_src.
* If PreP or FAT are desired, it creates MBR partition entries and
* surrounding protecting partition entries.
* If EFI boot partition is desired, it creates a GPT entry for it.
* >>> It shall learn to grab Ecma119Node instead of external disk files.
*/
ret = partprepend_writer_create(target);
if (ret < 0)
goto target_cleanup;
/* create writer for HFS+/FAT structure */
/* Impotant: It must be created directly before iso_file_src_writer_create.
*/
@ -2673,6 +2704,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
#endif /* Libisofs_with_libjtE */
wopts->tail_blocks = 0;
wopts->prep_partition = NULL;
wopts->efi_boot_partition = NULL;
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
wopts->appended_partitions[i] = NULL;
wopts->ascii_disc_label[0] = 0;
@ -2705,6 +2738,10 @@ void iso_write_opts_free(IsoWriteOpts *opts)
if (opts->system_area_data != NULL)
free(opts->system_area_data);
if (opts->prep_partition != NULL)
free(opts->prep_partition);
if (opts->efi_boot_partition != NULL)
free(opts->efi_boot_partition);
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
if (opts->appended_partitions[i] != NULL)
free(opts->appended_partitions[i]);
@ -3287,19 +3324,44 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks)
return ISO_SUCCESS;
}
int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path, int flag)
{
if (opts->prep_partition != NULL)
free(opts->prep_partition);
if (image_path == NULL)
return ISO_SUCCESS;
opts->prep_partition = strdup(image_path);
if (opts->prep_partition == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
int flag)
{
if (opts->efi_boot_partition != NULL)
free(opts->efi_boot_partition);
if (image_path == NULL)
return ISO_SUCCESS;
opts->efi_boot_partition = strdup(image_path);
if (opts->efi_boot_partition == NULL)
return ISO_OUT_OF_MEM;
return ISO_SUCCESS;
}
int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
uint8_t partition_type, char *image_path, int flag)
{
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
return ISO_BAD_PARTITION_NO;
if (opts->appended_partitions[partition_number - 1] != NULL)
free(opts->appended_partitions[partition_number - 1]);
if (image_path == NULL)
return ISO_SUCCESS;
opts->appended_partitions[partition_number - 1] = strdup(image_path);
if (opts->appended_partitions[partition_number - 1] == NULL)
return ISO_OUT_OF_MEM;
opts->appended_part_types[partition_number - 1] = partition_type;
return ISO_SUCCESS;
}

View File

@ -452,6 +452,16 @@ struct iso_write_opts {
*/
uint32_t tail_blocks;
/* Eventual disk file path of a PreP partition which shall be prepended
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
*/
char *prep_partition;
/* Eventual disk file path of an EFI system partition image which shall
be prepended to HFS+/FAT and IsoFileSrc areas and marked by a GPT entry.
*/
char *efi_boot_partition;
/* Eventual disk file paths of prepared images which shall be appended
after the ISO image and described by partiton table entries in a MBR
*/
@ -825,6 +835,9 @@ struct ecma119_image
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
int mbr_req_count;
char *prep_partition;
uint32_t prep_part_size;
/* GPT description. To be composed during IsoImageWriter
method ->compute_data_blocks() by calling iso_register_gpt_entry().
Make sure that the composing writers get registered before the
@ -833,6 +846,9 @@ struct ecma119_image
struct iso_gpt_partition_request *gpt_req[ISO_GPT_ENTRIES_MAX];
int gpt_req_count;
char *efi_boot_partition;
uint32_t efi_boot_part_size;
/* Messages from gpt_tail_writer_compute_data_blocks() to
iso_write_system_area().
*/
@ -986,4 +1002,8 @@ struct ecma119_vol_desc_terminator
void ecma119_set_voldescr_times(IsoImageWriter *writer,
struct ecma119_pri_vol_desc *vol);
/* Copies a data file into the ISO image output stream */
int iso_write_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -2326,6 +2326,65 @@ int iso_write_opts_detach_jte(IsoWriteOpts *opts, void **libjte_handle);
*/
int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
/**
* Copy a data file from the local filesystem into the emerging ISO image.
* Mark it by an MBR partition entry as PreP partition and also cause
* protective MBR partition entries before and after this partition.
* Vladimir Serbinenko stated aboy PreP = PowerPC Reference Platform :
* "PreP [...] refers mainly to IBM hardware. PreP boot is a partition
* containing only raw ELF and having type 0x41."
*
* This feature is only combinable with system area type 0
* >>> and currently not combinable with ISOLINUX isohybrid production.
* It overrides --protective-msdos-label. See iso_write_opts_set_system_area().
* Only partition 4 stays available for iso_write_opts_set_partition_img().
* It is compatible with HFS+/FAT production by storing the PreP partition
* before the start of the HFS+/FAT partition.
*
* @param opts
* The option set to be manipulated.
* @param image_path
* File address in the local file system.
* NULL revokes production of the PreP partition.
* @param flag
* Reserved for future usage, set to 0.
* @return
* ISO_SUCCESS or error
*
* @since 1.2.4
*/
int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path,
int flag);
/**
* Copy a data file from the local filesystem into the emerging ISO image.
* Mark it by an GPT partition entry as EFI System partition, and also cause
* protective GPT partition entries before and after the partition.
* GPT = Globally Unique Identifier Partition Table
*
* This feature may collide with data submitted by
* iso_write_opts_set_system_area()
* and with settings made by
* el_torito_set_isolinux_options()
* It is compatible with HFS+/FAT production by storing the EFI partition
* before the start of the HFS+/FAT partition.
* The GPT overwrites byte 0x0200 to 0x03ff of the system area and all
* further bytes above 0x0800 which are not used by an Apple Partition Map.
*
* @param opts
* The option set to be manipulated.
* @param image_path
* File address in the local file system.
* NULL revokes production of the EFI boot partition.
* @param flag
* Reserved for future usage, set to 0.
* @return
* ISO_SUCCESS or error
*
* @since 1.2.4
*/
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
int flag);
/**
* Cause an arbitrary data file to be appended to the ISO image and to be
@ -2353,6 +2412,8 @@ int iso_write_opts_set_tail_blocks(IsoWriteOpts *opts, uint32_t num_blocks);
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
* Linux Native Partition = 0x83. See fdisk command L.
* This parameter is ignored with SUN Disk Label.
* @param flag
* Reserved for future usage, set to 0.
* @return
* ISO_SUCCESS or error
*
@ -7197,7 +7258,7 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
/** Cannot open data file for appended partition (FAILURE, HIGH, -370) */
#define ISO_BAD_PARTITION_FILE 0xE830FE8E
/** May not combine appended partition with non-MBR system area
/** May not combine MBR partition with non-MBR system area
(FAILURE, HIGH, -371) */
#define ISO_NON_MBR_SYS_AREA 0xE830FE8D
@ -7254,9 +7315,12 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
/** Too many MBR partition entries requested (FAILURE, HIGH, -387) */
#define ISO_BOOT_TOO_MANY_MBR 0xE830FE7D
/** Overlapping MBR entries requested (FAILURE, HIGH, -388) */
/** Overlapping MBR partition entries requested (FAILURE, HIGH, -388) */
#define ISO_BOOT_MBR_OVERLAP 0xE830FE7C
/** Attempt to use an MBR partition entry twice (FAILURE, HIGH, -389) */
#define ISO_BOOT_MBR_COLLISION 0xE830FE7B
/* Internal developer note:

View File

@ -285,6 +285,7 @@ iso_write_opts_set_default_timestamp;
iso_write_opts_set_default_uid;
iso_write_opts_set_dir_rec_mtime;
iso_write_opts_set_disc_label;
iso_write_opts_set_efi_bootp;
iso_write_opts_set_fat;
iso_write_opts_set_fifo_size;
iso_write_opts_set_hardlinks;
@ -304,6 +305,7 @@ iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf;
iso_write_opts_set_part_offset;
iso_write_opts_set_partition_img;
iso_write_opts_set_prep_img;
iso_write_opts_set_pvd_times;
iso_write_opts_set_record_md5;
iso_write_opts_set_relaxed_vol_atts;

View File

@ -451,7 +451,7 @@ const char *iso_error_to_msg(int errcode)
case ISO_BAD_PARTITION_FILE:
return "Cannot open data file for appended partition";
case ISO_NON_MBR_SYS_AREA:
return "May not combine appended partition with non-MBR system area";
return "May not combine MBR partition with non-MBR system area";
case ISO_DISPLACE_ROLLOVER:
return "Displacement offset leads outside 32 bit range";
case ISO_NAME_NEEDS_TRANSL:
@ -485,7 +485,9 @@ const char *iso_error_to_msg(int errcode)
case ISO_BOOT_TOO_MANY_MBR:
return "Too many MBR partition entries requested";
case ISO_BOOT_MBR_OVERLAP:
return "Overlapping MBR entries requested";
return "Overlapping MBR partition entries requested";
case ISO_BOOT_MBR_COLLISION:
return "Attempt to use an MBR partition entry twice";
default:
return "Unknown error";
}

View File

@ -88,6 +88,25 @@ void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
}
}
static uint32_t compute_partition_size(char *disk_path, uint32_t *size,
int flag)
{
int ret;
off_t num;
struct stat stbuf;
*size = 0;
ret = stat(disk_path, &stbuf);
if (ret == -1)
return ISO_BAD_PARTITION_FILE;
if (! S_ISREG(stbuf.st_mode))
return ISO_BAD_PARTITION_FILE;
num = ((stbuf.st_size + 2047) / 2048);
if (num > 0x3fffffff || num == 0)
return ISO_BAD_PARTITION_FILE;
*size = num;
return ISO_SUCCESS;
}
/* Compute size and position of appended partitions.
*/
@ -95,7 +114,6 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
{
int ret, i, sa_type;
uint32_t pos, size, add_pos = 0;
struct stat stbuf;
sa_type = (t->system_area_options >> 2) & 0x3f;
pos = (t->vol_space_size + t->ms_block);
@ -104,12 +122,9 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
continue;
if (t->appended_partitions[i][0] == 0)
continue;
ret = stat(t->appended_partitions[i], &stbuf);
if (ret == -1)
return ISO_BAD_PARTITION_FILE;
if (! S_ISREG(stbuf.st_mode))
return ISO_BAD_PARTITION_FILE;
size = ((stbuf.st_size + 2047) / 2048);
ret = compute_partition_size(t->appended_partitions[i], &size, 0);
if (ret < 0)
return ret;
if (sa_type == 3 && (pos % ISO_SUN_CYL_SIZE))
add_pos = ISO_SUN_CYL_SIZE - (pos % ISO_SUN_CYL_SIZE);
t->appended_part_prepad[i] = add_pos;
@ -1367,6 +1382,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
"Cannot set up MBR partition table");
return ret;
}
if (t->mbr_req_count > 0 && sa_type != 0)
return ISO_NON_MBR_SYS_AREA;
ret = iso_write_gpt(t, img_blocks, buf);
if (ret < 0) {
iso_msg_submit(t->image->id, ret, 0, "Cannot set up GPT");
@ -1374,11 +1391,14 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
}
if (sa_type == 0 && (t->system_area_options & 1)) {
/* Write GRUB protective msdos label, i.e. a simple partition table */
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 0);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
if (t->mbr_req_count == 0){
/* Write GRUB protective msdos label, i.e. a simple partition
table */
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 0);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
}
} else if(sa_type == 0 && (t->system_area_options & 2)) {
/* Patch externally provided system area as isohybrid MBR */
if (t->catalog == NULL || t->system_area_data == NULL) {
@ -1396,6 +1416,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
Would it harm to give the real offset here ?
*/;
/* >>> Coordinate with partprepend writer */
/* <<< provisory trap */
if (t->mbr_req_count > 0)
return ISO_BOOT_MBR_OVERLAP;
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, 0x17, buf, 1);
if (ret != 1)
return ret;
@ -1407,7 +1432,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
ret = make_mipsel_boot_block(t, buf, 0);
if (ret != ISO_SUCCESS)
return ret;
} else if ((t->partition_offset > 0 || will_append) && sa_type == 0) {
} else if (sa_type == 3) {
ret = make_sun_disk_label(t, buf, 0);
if (ret != ISO_SUCCESS)
return ret;
} else if ((t->partition_offset > 0 || will_append) && sa_type == 0 &&
t->mbr_req_count == 0) {
/* Write a simple partition table. */
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 2);
@ -1421,14 +1451,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (ret < 0)
return ret;
}
} else if (sa_type == 3) {
ret = make_sun_disk_label(t, buf, 0);
if (ret != ISO_SUCCESS)
return ret;
}
if (t->partition_offset > 0 && sa_type == 0) {
/* Adjust partition table to partition offset */
if (t->partition_offset > 0 && sa_type == 0 && t->mbr_req_count == 0) {
/* Adjust partition table to partition offset.
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->partition_offset,
t->partition_secs_per_head,
@ -1437,17 +1465,21 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ISO_ASSERT_FAILURE;
}
/* This eventually overwrites the partition table entries made so far */
/* 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->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->appended_partitions,
ret = write_sun_partition_entry(i + 1, t->appended_partitions,
t->appended_part_start, t->appended_part_size,
ISO_SUN_CYL_SIZE,
buf, t->appended_partitions[i][0] == 0);
} else {
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
ret = write_mbr_partition_entry(i + 1, t->appended_part_types[i],
t->appended_part_start[i], t->appended_part_size[i],
t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 0);
@ -1954,3 +1986,134 @@ int gpt_tail_writer_create(Ecma119Image *target)
return ISO_SUCCESS;
}
/* ---------------------- Partition Prepend Writer --------------------- */
static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
{
Ecma119Image *t;
int ret, will_have_gpt = 0;
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
uint8_t gpt_name[72];
/* <<< ??? Move to system_area.h and publish as macro ? */
static uint8_t efi_sys_uuid[16] = {
0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
};
if (writer == NULL)
return ISO_ASSERT_FAILURE;
t = writer->target;
/* >>> t->chrp_mark */;
if (t->efi_boot_partition != NULL) {
ret = compute_partition_size(t->efi_boot_partition,
&(t->efi_boot_part_size), 0);
if (ret < 0)
return ret;
memset(gpt_name, 0, 72);
strcpy((char *) gpt_name, "EFI boot partition");
poor_man_s_utf_16le(gpt_name);
ret = iso_quick_gpt_entry(t, t->curblock, t->efi_boot_part_size,
efi_sys_uuid, zero_uuid, gpt_flags, gpt_name);
if (ret < 0)
return ret;
t->curblock += t->efi_boot_part_size;
}
if (t->efi_boot_partition != NULL || t->hfsplus)
will_have_gpt = 1;
if (t->prep_partition != NULL) {
ret = compute_partition_size(t->prep_partition, &(t->prep_part_size),
0);
if (ret < 0)
return ret;
}
if (t->prep_part_size > 0 || t->fat || will_have_gpt) {
/* Protecting MBR entry for ISO start or whole ISO */
ret = iso_quick_mbr_entry(t, (uint32_t) t->partition_offset,
(uint32_t) 0, will_have_gpt ? 0xee : 0xcd, 0);
if (ret < 0)
return ret;
}
if (t->prep_part_size > 0) {
ret = iso_quick_mbr_entry(t, t->curblock, t->prep_part_size, 0x41, 0);
if (ret < 0)
return ret;
t->curblock += t->prep_part_size;
}
if (t->prep_part_size > 0 || t->fat) {
/* FAT partition or protecting MBR entry for ISO end */
ret = iso_quick_mbr_entry(t, (uint32_t) t->curblock, (uint32_t) 0,
t->fat ? 0x0c : 0xcd, 0);
if (ret < 0)
return ret;
}
return ISO_SUCCESS;
}
static int partprepend_writer_write_vol_desc(IsoImageWriter *writer)
{
return ISO_SUCCESS;
}
static int partprepend_writer_write_data(IsoImageWriter *writer)
{
Ecma119Image *t;
int ret;
t = writer->target;
if (t->efi_boot_partition != NULL && t->efi_boot_part_size) {
ret = iso_write_partition_file(t, t->efi_boot_partition, (uint32_t) 0,
t->efi_boot_part_size, 0);
if (ret < 0)
return ret;
}
if (t->prep_partition != NULL && t->prep_part_size) {
ret = iso_write_partition_file(t, t->prep_partition, (uint32_t) 0,
t->prep_part_size, 0);
if (ret < 0)
return ret;
}
return ISO_SUCCESS;
}
static int partprepend_writer_free_data(IsoImageWriter *writer)
{
return ISO_SUCCESS;
}
int partprepend_writer_create(Ecma119Image *target)
{
IsoImageWriter *writer;
writer = calloc(1, sizeof(IsoImageWriter));
if (writer == NULL) {
return ISO_OUT_OF_MEM;
}
writer->compute_data_blocks = partprepend_writer_compute_data_blocks;
writer->write_vol_desc = partprepend_writer_write_vol_desc;
writer->write_data = partprepend_writer_write_data;
writer->free_data = partprepend_writer_free_data;
writer->data = NULL;
writer->target = target;
/* add this writer to image */
target->writers[target->nwriters++] = writer;
return ISO_SUCCESS;
}

View File

@ -234,6 +234,10 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
uint8_t *buf, uint32_t max_entries,
uint32_t part_start, uint32_t p_arr_crc);
/* Creates the Partition Prepend writer.
*/
int partprepend_writer_create(Ecma119Image *target);
/* Creates the GPT backup tail writer.
*/
int gpt_tail_writer_create(Ecma119Image *target);