From 6a3273dc722bf76f8f3900333cea6799373d64fb Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 12 Jun 2012 13:24:50 +0200 Subject: [PATCH] New API calls so_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp() --- libisofs/ecma119.c | 78 ++++++++++++++-- libisofs/ecma119.h | 20 ++++ libisofs/libisofs.h | 68 +++++++++++++- libisofs/libisofs.ver | 2 + libisofs/messages.c | 6 +- libisofs/system_area.c | 207 ++++++++++++++++++++++++++++++++++++----- libisofs/system_area.h | 4 + 7 files changed, 351 insertions(+), 34 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 0499579..f1ab0e0 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -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; } diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index 36a4319..07f761b 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -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_*/ diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 84a5a05..fc2c149 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -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: diff --git a/libisofs/libisofs.ver b/libisofs/libisofs.ver index 9336f11..3e3a56e 100644 --- a/libisofs/libisofs.ver +++ b/libisofs/libisofs.ver @@ -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; diff --git a/libisofs/messages.c b/libisofs/messages.c index 8475900..46635e4 100644 --- a/libisofs/messages.c +++ b/libisofs/messages.c @@ -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"; } diff --git a/libisofs/system_area.c b/libisofs/system_area.c index 6d2070a..8193722 100644 --- a/libisofs/system_area.c +++ b/libisofs/system_area.c @@ -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; +} + + diff --git a/libisofs/system_area.h b/libisofs/system_area.h index 37c970e..6dee105 100644 --- a/libisofs/system_area.h +++ b/libisofs/system_area.h @@ -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);