New API call iso_write_opts_set_hfsp_block_size().
This commit is contained in:
parent
7e49fb553b
commit
2d441cca5d
@ -1920,7 +1920,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (target->hfsplus_blessed[i] != NULL)
|
||||
iso_node_ref(target->hfsplus_blessed[i]);
|
||||
}
|
||||
target->apm_block_size = 512;
|
||||
target->apm_block_size = opts->apm_block_size;
|
||||
target->hfsp_block_size = opts->hfsp_block_size;
|
||||
target->hfsp_cat_node_size = 0;
|
||||
target->hfsp_iso_block_fac = 0;
|
||||
target->apm_req_count = 0;
|
||||
target->apm_req_flags = 0;
|
||||
for (i = 0; i < ISO_APM_ENTRIES_MAX; i++)
|
||||
@ -2356,6 +2359,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
image_checksums_mad = 0;
|
||||
|
||||
if (target->apm_block_size == 0) {
|
||||
if (target->gpt_req_count)
|
||||
target->apm_block_size = 2048; /* Combinable with GPT */
|
||||
else
|
||||
target->apm_block_size = 512; /* Mountable on Linux */
|
||||
}
|
||||
|
||||
/* ensure the thread is created joinable */
|
||||
pthread_attr_init(&(target->th_attr));
|
||||
pthread_attr_setdetachstate(&(target->th_attr), PTHREAD_CREATE_JOINABLE);
|
||||
@ -2739,6 +2749,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->untranslated_name_len = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
wopts->hfsp_serial_number[i] = 0;
|
||||
wopts->apm_block_size = 0;
|
||||
wopts->hfsp_block_size = 0;
|
||||
|
||||
*opts = wopts;
|
||||
return ISO_SUCCESS;
|
||||
@ -3403,4 +3415,18 @@ int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
|
||||
memcpy(opts->hfsp_serial_number, serial_number, 8);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
|
||||
int hfsp_block_size, int apm_block_size)
|
||||
{
|
||||
if (hfsp_block_size != 0 && hfsp_block_size != 512 &&
|
||||
hfsp_block_size != 2048)
|
||||
return ISO_BOOT_HFSP_BAD_BSIZE;
|
||||
opts->hfsp_block_size = hfsp_block_size;
|
||||
if (apm_block_size != 0 && apm_block_size != 512 && apm_block_size != 2048)
|
||||
return ISO_BOOT_HFSP_BAD_BSIZE;
|
||||
opts->apm_block_size = apm_block_size;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -477,6 +477,14 @@ struct iso_write_opts {
|
||||
*/
|
||||
uint8_t hfsp_serial_number[8];
|
||||
|
||||
/* Allocation block size of HFS+ : 0= auto , 512, or 2048
|
||||
*/
|
||||
int hfsp_block_size;
|
||||
|
||||
/* Block size of and in APM : 0= auto , 512, or 2048
|
||||
*/
|
||||
int apm_block_size;
|
||||
|
||||
};
|
||||
|
||||
typedef struct ecma119_image Ecma119Image;
|
||||
@ -819,6 +827,22 @@ struct ecma119_image
|
||||
/* See IsoImage and libisofs.h */
|
||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||
|
||||
/* Block sizes come from write options.
|
||||
Only change a block size if it is 0. Set only to 512 or 2048.
|
||||
If it stays 0 then it will become 512 or 2048 in time.
|
||||
*/
|
||||
/* Blocksize of Apple Partition Map
|
||||
May be defined to 512 or 2048 before writer thread starts.
|
||||
*/
|
||||
int apm_block_size;
|
||||
|
||||
/* Allocation block size of HFS+
|
||||
May be defined to 512 or 2048 before hfsplus_writer_create().
|
||||
*/
|
||||
int hfsp_block_size;
|
||||
int hfsp_cat_node_size; /* 2 * apm_block_size */
|
||||
int hfsp_iso_block_fac; /* 2048 / apm_block_size */
|
||||
|
||||
/* Apple Partition Map description. To be composed during IsoImageWriter
|
||||
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
||||
Make sure that the composing writers get registered before the
|
||||
@ -826,9 +850,10 @@ struct ecma119_image
|
||||
*/
|
||||
struct iso_apm_partition_request *apm_req[ISO_APM_ENTRIES_MAX];
|
||||
int apm_req_count;
|
||||
/* 512 by default. May be changed to 2048 before writer thread starts. */
|
||||
int apm_block_size;
|
||||
/* bit1= Do not fill gaps in Apple Partition Map */
|
||||
/* bit1= Do not fill gaps in Apple Partition Map
|
||||
bit2= apm_req entries use apm_block_size in start_block and block_count.
|
||||
Normally these two parameters are counted in 2 KiB blocks.
|
||||
*/
|
||||
int apm_req_flags;
|
||||
|
||||
/* MBR partition table description. To be composed during IsoImageWriter
|
||||
|
@ -20,6 +20,16 @@
|
||||
#define Libisofs_ts_debuG yes
|
||||
|
||||
|
||||
/* Do not fill gaps in APM.
|
||||
<<< provisory , rather not
|
||||
# define Libisofs_hfsplus_no_gap_filL yes
|
||||
*/
|
||||
|
||||
/* Avoid ISO block padding in hfsplus_tail_writer
|
||||
<<< provisory , rather not
|
||||
# define Libisofs_apm_flags_bit2 yes
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -41,10 +51,16 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HFSPLUS_BLOCK_SIZE 2048
|
||||
#define HFSPLUS_CAT_NODE_SIZE (2 * HFSPLUS_BLOCK_SIZE)
|
||||
/* To be used if Ecma119.hfsplus_block_size == 0 in hfsplus_writer_create().
|
||||
It cannot be larger than 2048 because filesrc_writer aligns data file
|
||||
content start to 2048.
|
||||
*/
|
||||
#define HFSPLUS_DEFAULT_BLOCK_SIZE 2048
|
||||
|
||||
/* To be used with storage allocation.
|
||||
*/
|
||||
#define HFSPLUS_MAX_BLOCK_SIZE 2048
|
||||
|
||||
#define HFSPLUS_ISO_BLOCK_FAC (2048 / HFSPLUS_BLOCK_SIZE)
|
||||
|
||||
#include <arpa/inet.h>
|
||||
/* For these prototypes:
|
||||
@ -311,8 +327,8 @@ int create_tree(Ecma119Image *t, IsoNode *iso, uint32_t parent_id)
|
||||
if (t->hfsplus_blessed[i] == iso) {
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus bless %d to cat_id %u ('%s')",
|
||||
i, cat_id, iso->name);
|
||||
iso_msg_debug(t->image->id, "hfsplus bless %d to cat_id %u ('%s')",
|
||||
i, cat_id, iso->name);
|
||||
#endif /* Libisofs_ts_debuG */
|
||||
|
||||
t->hfsp_bless_id[i] = cat_id;
|
||||
@ -417,100 +433,141 @@ cmp_node(const void *f1, const void *f2)
|
||||
return ucscmp(a, b);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
uint32_t hfsp_size;
|
||||
|
||||
uint32_t hfsp_size, hfsp_curblock, block_fac, block_size;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_fac = t->hfsp_iso_block_fac;
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer start = %.f",
|
||||
((double) t->curblock) * 2048.0);
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer start = %.f",
|
||||
((double) t->curblock) * 2048.0);
|
||||
#endif
|
||||
|
||||
hfsp_size = t->curblock * HFSPLUS_ISO_BLOCK_FAC - t->hfsp_part_start + 1;
|
||||
hfsp_curblock = t->curblock * block_fac;
|
||||
hfsp_size = hfsp_curblock - t->hfsp_part_start + 1;
|
||||
|
||||
/* We need one bit for every block. */
|
||||
/* So if we allocate x blocks we have to satisfy:
|
||||
8 * HFSPLUS_BLOCK_SIZE * x >= total_size + x
|
||||
(8 * HFSPLUS_BLOCK_SIZE - 1) * x >= total_size
|
||||
8 * block_size * x >= total_size + x
|
||||
(8 * block_size - 1) * x >= total_size
|
||||
*/
|
||||
t->hfsp_allocation_blocks = hfsp_size
|
||||
/ (8 * HFSPLUS_BLOCK_SIZE - 1) + 1;
|
||||
t->hfsp_allocation_file_start = t->curblock * HFSPLUS_ISO_BLOCK_FAC;
|
||||
t->curblock += t->hfsp_allocation_blocks / HFSPLUS_ISO_BLOCK_FAC;
|
||||
if (t->hfsp_allocation_blocks % HFSPLUS_ISO_BLOCK_FAC)
|
||||
t->hfsp_allocation_blocks = hfsp_size / (8 * block_size - 1) + 1;
|
||||
t->hfsp_allocation_file_start = hfsp_curblock;
|
||||
hfsp_curblock += t->hfsp_allocation_blocks;
|
||||
|
||||
#ifdef Libisofs_apm_flags_bit2
|
||||
|
||||
/* Superblock always occupies 2K */
|
||||
hfsp_curblock += block_fac;
|
||||
|
||||
/* write_data() will need to pad up ISO block after superblock copy */
|
||||
t->curblock = hfsp_curblock / block_fac;
|
||||
if (hfsp_curblock % block_fac)
|
||||
t->curblock++;
|
||||
|
||||
#else /* Libisofs_apm_flags_bit2 */
|
||||
|
||||
/* write_data() will need to pad up ISO block before superblock copy */
|
||||
t->curblock = hfsp_curblock / block_fac;
|
||||
if (hfsp_curblock % block_fac)
|
||||
t->curblock++;
|
||||
hfsp_curblock = t->curblock * block_fac;
|
||||
|
||||
/* Superblock always occupies 2K */
|
||||
hfsp_curblock += block_fac;
|
||||
t->curblock++;
|
||||
|
||||
#endif /* ! Libisofs_apm_flags_bit4 */
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer end = %.f",
|
||||
((double) t->curblock) * 2048.0);
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer end = %.f",
|
||||
((double) hfsp_curblock) * block_size);
|
||||
#endif
|
||||
|
||||
t->hfsp_total_blocks = t->curblock * HFSPLUS_ISO_BLOCK_FAC
|
||||
- t->hfsp_part_start;
|
||||
t->apm_block_size = HFSPLUS_BLOCK_SIZE;
|
||||
return iso_quick_apm_entry(t, t->hfsp_part_start / HFSPLUS_ISO_BLOCK_FAC,
|
||||
t->hfsp_total_blocks / HFSPLUS_ISO_BLOCK_FAC +
|
||||
!!(t->hfsp_total_blocks % HFSPLUS_ISO_BLOCK_FAC),
|
||||
t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start;
|
||||
|
||||
#ifdef Libisofs_hfsplus_no_gap_filL
|
||||
/* <<< test B20625 : leave out gap filling */
|
||||
t->apm_req_flags |= 2;
|
||||
#endif /* Libisofs_hfsplus_no_gap_filL */
|
||||
|
||||
#ifdef Libisofs_apm_flags_bit2
|
||||
|
||||
t->apm_req_flags |= 4;
|
||||
return iso_quick_apm_entry(t, t->hfsp_part_start,
|
||||
t->hfsp_total_blocks,
|
||||
"HFSPLUS_Hybrid", "Apple_HFS");
|
||||
|
||||
#else /* Libisofs_apm_flags_bit2 */
|
||||
|
||||
return iso_quick_apm_entry(t, t->hfsp_part_start / block_fac,
|
||||
t->hfsp_total_blocks / block_fac +
|
||||
!!(t->hfsp_total_blocks % block_fac),
|
||||
"HFSPLUS_Hybrid", "Apple_HFS");
|
||||
|
||||
#endif /* ! Libisofs_apm_flags_bit2 */
|
||||
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
uint32_t i, link_blocks;
|
||||
uint32_t i, link_blocks, hfsp_curblock;
|
||||
uint32_t block_fac, cat_node_size, block_size;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_fac = t->hfsp_iso_block_fac;
|
||||
cat_node_size = t->hfsp_cat_node_size;
|
||||
|
||||
iso_msg_debug(t->image->id, "(b) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes);
|
||||
t->hfsp_part_start = t->curblock * HFSPLUS_ISO_BLOCK_FAC;
|
||||
t->hfsp_part_start = t->curblock * block_fac;
|
||||
|
||||
t->curblock++;
|
||||
hfsp_curblock = t->curblock * block_fac;
|
||||
|
||||
t->hfsp_catalog_file_start = t->curblock * HFSPLUS_ISO_BLOCK_FAC;
|
||||
/* Superblock always occupies 2K */
|
||||
hfsp_curblock += block_fac;
|
||||
|
||||
/* ts B20623 was:
|
||||
t->curblock += 2 * t->hfsp_nnodes;
|
||||
t->hfsp_catalog_file_start = hfsp_curblock;
|
||||
|
||||
/*
|
||||
hfsp_curblock += (t->hfsp_nnodes * cat_node_size + block_size - 1) / block_size;
|
||||
*/
|
||||
t->curblock += (t->hfsp_nnodes * HFSPLUS_CAT_NODE_SIZE + 2047) / 2048;
|
||||
hfsp_curblock += 2 * t->hfsp_nnodes;
|
||||
|
||||
t->hfsp_extent_file_start = t->curblock * HFSPLUS_ISO_BLOCK_FAC;
|
||||
t->curblock++;
|
||||
t->hfsp_extent_file_start = hfsp_curblock;
|
||||
hfsp_curblock++;
|
||||
|
||||
iso_msg_debug(t->image->id, "(d) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes);
|
||||
iso_msg_debug(t->image->id, "(d) hfsp_curblock=%d, nodes =%d", hfsp_curblock, t->hfsp_nnodes);
|
||||
|
||||
link_blocks = 0;
|
||||
for (i = 0; i < t->hfsp_nleafs; i++)
|
||||
if (t->hfsp_leafs[i].unix_type == UNIX_SYMLINK)
|
||||
{
|
||||
|
||||
/* ts B20623 : was:
|
||||
t->hfsp_leafs[i].symlink_block = t->curblock;
|
||||
t->curblock += (t->hfsp_leafs[i].symlink_size + HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_BLOCK_SIZE;
|
||||
*/
|
||||
t->hfsp_leafs[i].symlink_block = hfsp_curblock;
|
||||
hfsp_curblock += (t->hfsp_leafs[i].symlink_size + block_size - 1) / block_size;
|
||||
|
||||
t->hfsp_leafs[i].symlink_block =
|
||||
t->curblock * HFSPLUS_ISO_BLOCK_FAC + link_blocks;
|
||||
link_blocks += (t->hfsp_leafs[i].symlink_size +
|
||||
HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* ts B20623 */
|
||||
t->curblock += link_blocks / HFSPLUS_ISO_BLOCK_FAC;
|
||||
if (link_blocks % HFSPLUS_ISO_BLOCK_FAC)
|
||||
t->curblock = hfsp_curblock / block_fac;
|
||||
if (hfsp_curblock % block_fac)
|
||||
t->curblock++;
|
||||
|
||||
iso_msg_debug(t->image->id, "(a) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes);
|
||||
@ -518,6 +575,7 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void set_time (uint32_t *tm, uint32_t t)
|
||||
{
|
||||
iso_msb ((uint8_t *) tm, t + 2082844800, 4);
|
||||
@ -570,9 +628,12 @@ write_sb (Ecma119Image *t)
|
||||
static char buffer[1024];
|
||||
int ret;
|
||||
int i;
|
||||
uint32_t block_size;
|
||||
|
||||
iso_msg_debug(t->image->id, "Write HFS+ superblock");
|
||||
|
||||
block_size = t->hfsp_block_size;
|
||||
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
ret = iso_write(t, buffer, 1024);
|
||||
if (ret < 0)
|
||||
@ -592,28 +653,28 @@ write_sb (Ecma119Image *t)
|
||||
set_time (&sb.fsck_time, t->now);
|
||||
iso_msb ((uint8_t *) &sb.file_count, t->hfsp_nfiles, 4);
|
||||
iso_msb ((uint8_t *) &sb.folder_count, t->hfsp_ndirs - 1, 4);
|
||||
iso_msb ((uint8_t *) &sb.blksize, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.blksize, block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_node_id, t->hfsp_cat_id, 4);
|
||||
iso_msb ((uint8_t *) &sb.rsrc_clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.data_clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.rsrc_clumpsize, block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.data_clumpsize, block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.total_blocks, t->hfsp_total_blocks, 4);
|
||||
iso_msb ((uint8_t *) &sb.encodings_bitmap + 4, 1, 4);
|
||||
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.size + 4, t->hfsp_allocation_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.blocks, (t->hfsp_allocation_size + HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.clumpsize, block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.blocks, (t->hfsp_allocation_size + block_size - 1) / block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.extents[0].start, t->hfsp_allocation_file_start - t->hfsp_part_start, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.extents[0].count, (t->hfsp_allocation_size + HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.allocations_file.extents[0].count, (t->hfsp_allocation_size + block_size - 1) / block_size, 4);
|
||||
|
||||
iso_msb ((uint8_t *) &sb.extents_file.size + 4, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.extents_file.clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &sb.extents_file.size + 4, block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.extents_file.clumpsize, block_size, 4);
|
||||
iso_msb ((uint8_t *) &sb.extents_file.blocks, 1, 4);
|
||||
iso_msb ((uint8_t *) &sb.extents_file.extents[0].start, t->hfsp_extent_file_start - t->hfsp_part_start, 4);
|
||||
iso_msb ((uint8_t *) &sb.extents_file.extents[0].count, 1, 4);
|
||||
iso_msg_debug(t->image->id, "extent_file_start = %d\n", (int)t->hfsp_extent_file_start);
|
||||
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.size + 4, HFSPLUS_BLOCK_SIZE * 2 * t->hfsp_nnodes, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.clumpsize, HFSPLUS_BLOCK_SIZE * 2, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.size + 4, block_size * 2 * t->hfsp_nnodes, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.clumpsize, block_size * 2, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.blocks, 2 * t->hfsp_nnodes, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.extents[0].start, t->hfsp_catalog_file_start - t->hfsp_part_start, 4);
|
||||
iso_msb ((uint8_t *) &sb.catalog_file.extents[0].count, 2 * t->hfsp_nnodes, 4);
|
||||
@ -625,8 +686,8 @@ write_sb (Ecma119Image *t)
|
||||
t->hfsp_bless_id[i], 4);
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus bless %d written for cat_id %u",
|
||||
i, t->hfsp_bless_id[i]);
|
||||
iso_msg_debug(t->image->id, "hfsplus bless %d written for cat_id %u",
|
||||
i, t->hfsp_bless_id[i]);
|
||||
#endif /* Libisofs_ts_debuG */
|
||||
|
||||
}
|
||||
@ -642,18 +703,21 @@ static
|
||||
int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
static char buffer[2 * HFSPLUS_BLOCK_SIZE];
|
||||
static char buffer[2 * HFSPLUS_MAX_BLOCK_SIZE];
|
||||
Ecma119Image *t;
|
||||
struct hfsplus_btnode *node_head;
|
||||
struct hfsplus_btheader *tree_head;
|
||||
int level;
|
||||
uint32_t curpos = 1, i;
|
||||
uint32_t curpos = 1, i, block_fac, cat_node_size, block_size;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_fac = t->hfsp_iso_block_fac;
|
||||
cat_node_size = t->hfsp_cat_node_size;
|
||||
|
||||
iso_msg_debug(t->image->id, "(b) %d written", (int) t->bytes_written / 0x800);
|
||||
|
||||
@ -675,27 +739,27 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||
iso_msb ((uint8_t *) &tree_head->leaf_records, t->hfsp_nleafs, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->first_leaf_node, t->hfsp_nnodes - t->hfsp_levels[0].level_size, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->last_leaf_node, t->hfsp_nnodes - 1, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->nodesize, HFSPLUS_CAT_NODE_SIZE, 2);
|
||||
iso_msb ((uint8_t *) &tree_head->nodesize, cat_node_size, 2);
|
||||
iso_msb ((uint8_t *) &tree_head->keysize, 6 + 2 * LIBISO_HFSPLUS_NAME_MAX, 2);
|
||||
iso_msb ((uint8_t *) &tree_head->total_nodes, t->hfsp_nnodes, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->free_nodes, 0, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->clump_size, HFSPLUS_CAT_NODE_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->clump_size, cat_node_size, 4);
|
||||
tree_head->key_compare = 0xcf;
|
||||
iso_msb ((uint8_t *) &tree_head->attributes, 2 | 4, 4);
|
||||
memset (buffer + 0xf8, -1, t->hfsp_nnodes / 8);
|
||||
buffer[0xf8 + (t->hfsp_nnodes / 8)] = 0xff00 >> (t->hfsp_nnodes % 8);
|
||||
|
||||
buffer[HFSPLUS_CAT_NODE_SIZE - 1] = sizeof (*node_head);
|
||||
buffer[HFSPLUS_CAT_NODE_SIZE - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
||||
buffer[HFSPLUS_CAT_NODE_SIZE - 5] = (char) 0xf8;
|
||||
buffer[HFSPLUS_CAT_NODE_SIZE - 7] = (char) ((HFSPLUS_CAT_NODE_SIZE - 8) & 0xff);
|
||||
buffer[HFSPLUS_CAT_NODE_SIZE - 8] = (HFSPLUS_CAT_NODE_SIZE - 8) >> 8;
|
||||
buffer[cat_node_size - 1] = sizeof (*node_head);
|
||||
buffer[cat_node_size - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
||||
buffer[cat_node_size - 5] = (char) 0xf8;
|
||||
buffer[cat_node_size - 7] = (char) ((cat_node_size - 8) & 0xff);
|
||||
buffer[cat_node_size - 8] = (cat_node_size - 8) >> 8;
|
||||
|
||||
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||
iso_msg_debug(t->image->id, "Write\n");
|
||||
#endif
|
||||
|
||||
ret = iso_write(t, buffer, HFSPLUS_CAT_NODE_SIZE);
|
||||
ret = iso_write(t, buffer, cat_node_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -720,7 +784,7 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||
curoff = sizeof (struct hfsplus_btnode);
|
||||
for (j = 0; j < t->hfsp_levels[level].nodes[i].cnt; j++)
|
||||
{
|
||||
iso_msb ((uint8_t *) buffer + HFSPLUS_CAT_NODE_SIZE - j * 2 - 2, curoff, 2);
|
||||
iso_msb ((uint8_t *) buffer + cat_node_size - j * 2 - 2, curoff, 2);
|
||||
|
||||
iso_msb ((uint8_t *) buffer + curoff, 2 * t->hfsp_levels[level - 1].nodes[curnode].strlen + 6, 2);
|
||||
iso_msb ((uint8_t *) buffer + curoff + 2, t->hfsp_levels[level - 1].nodes[curnode].parent_id, 4);
|
||||
@ -732,13 +796,13 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||
curoff += 4;
|
||||
curnode++;
|
||||
}
|
||||
iso_msb ((uint8_t *) buffer + HFSPLUS_CAT_NODE_SIZE - j * 2 - 2, curoff, 2);
|
||||
iso_msb ((uint8_t *) buffer + cat_node_size - j * 2 - 2, curoff, 2);
|
||||
|
||||
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||
iso_msg_debug(t->image->id, "Write\n");
|
||||
#endif
|
||||
|
||||
ret = iso_write(t, buffer, HFSPLUS_CAT_NODE_SIZE);
|
||||
ret = iso_write(t, buffer, cat_node_size);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -766,7 +830,7 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||
curoff = sizeof (struct hfsplus_btnode);
|
||||
for (j = 0; j < t->hfsp_levels[level].nodes[i].cnt; j++)
|
||||
{
|
||||
iso_msb ((uint8_t *) buffer + HFSPLUS_CAT_NODE_SIZE - j * 2 - 2, curoff, 2);
|
||||
iso_msb ((uint8_t *) buffer + cat_node_size - j * 2 - 2, curoff, 2);
|
||||
|
||||
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||
|
||||
@ -920,16 +984,16 @@ iso_msg_debug(t->image->id,
|
||||
&blk, &sz);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
blk *= HFSPLUS_ISO_BLOCK_FAC;
|
||||
blk *= block_fac;
|
||||
}
|
||||
if (sz == 0)
|
||||
blk = t->hfsp_part_start;
|
||||
iso_msb ((uint8_t *) &data_fork->size, sz >> 32, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->size + 4, sz, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->blocks, (sz + HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->clumpsize, block_size, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->blocks, (sz + block_size - 1) / block_size, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->extents[0].start, blk - t->hfsp_part_start, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->extents[0].count, (sz + HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &data_fork->extents[0].count, (sz + block_size - 1) / block_size, 4);
|
||||
|
||||
curoff += sizeof (*data_fork) * 2;
|
||||
/* FIXME: resource fork */
|
||||
@ -939,13 +1003,13 @@ iso_msg_debug(t->image->id,
|
||||
}
|
||||
curnode++;
|
||||
}
|
||||
iso_msb ((uint8_t *) buffer + HFSPLUS_CAT_NODE_SIZE - j * 2 - 2, curoff, 2);
|
||||
iso_msb ((uint8_t *) buffer + cat_node_size - j * 2 - 2, curoff, 2);
|
||||
|
||||
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||
iso_msg_debug(t->image->id, "Write\n");
|
||||
#endif
|
||||
|
||||
ret = iso_write(t, buffer, HFSPLUS_CAT_NODE_SIZE);
|
||||
ret = iso_write(t, buffer, cat_node_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -953,38 +1017,30 @@ iso_msg_debug(t->image->id,
|
||||
}
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
|
||||
ret = pad_up_block(t);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
iso_msg_debug(t->image->id, "real extent_file_start = %d\n", (int)t->bytes_written / 2048);
|
||||
|
||||
node_head = (struct hfsplus_btnode *) buffer;
|
||||
node_head->type = 1;
|
||||
iso_msb ((uint8_t *) &node_head->count, 3, 2);
|
||||
tree_head = (struct hfsplus_btheader *) (node_head + 1);
|
||||
iso_msb ((uint8_t *) &tree_head->nodesize, HFSPLUS_BLOCK_SIZE, 2);
|
||||
iso_msb ((uint8_t *) &tree_head->nodesize, block_size, 2);
|
||||
iso_msb ((uint8_t *) &tree_head->keysize, 10, 2);
|
||||
iso_msb ((uint8_t *) &tree_head->total_nodes, 1, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->free_nodes, 0, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->clump_size, HFSPLUS_BLOCK_SIZE, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->clump_size, block_size, 4);
|
||||
iso_msb ((uint8_t *) &tree_head->attributes, 2, 4);
|
||||
buffer[0xf8] = (char) 0x80;
|
||||
|
||||
buffer[HFSPLUS_BLOCK_SIZE - 1] = sizeof (*node_head);
|
||||
buffer[HFSPLUS_BLOCK_SIZE - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
||||
buffer[HFSPLUS_BLOCK_SIZE - 5] = (char) 0xf8;
|
||||
buffer[HFSPLUS_BLOCK_SIZE - 7] = (char) ((HFSPLUS_BLOCK_SIZE - 8) & 0xff);
|
||||
buffer[HFSPLUS_BLOCK_SIZE - 8] = (HFSPLUS_BLOCK_SIZE - 8) >> 8;
|
||||
buffer[block_size - 1] = sizeof (*node_head);
|
||||
buffer[block_size - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
||||
buffer[block_size - 5] = (char) 0xf8;
|
||||
buffer[block_size - 7] = (char) ((block_size - 8) & 0xff);
|
||||
buffer[block_size - 8] = (block_size - 8) >> 8;
|
||||
|
||||
ret = iso_write(t, buffer, HFSPLUS_BLOCK_SIZE);
|
||||
ret = iso_write(t, buffer, block_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = pad_up_block(t);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
iso_msg_debug(t->image->id, "(d) %d written", (int) t->bytes_written / 0x800);
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
for (i = 0; i < t->hfsp_nleafs; i++)
|
||||
@ -995,14 +1051,15 @@ iso_msg_debug(t->image->id,
|
||||
ret = iso_write(t, sym->dest, t->hfsp_leafs[i].symlink_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
overhead = t->hfsp_leafs[i].symlink_size % HFSPLUS_BLOCK_SIZE;
|
||||
overhead = t->hfsp_leafs[i].symlink_size % block_size;
|
||||
if (overhead)
|
||||
overhead = HFSPLUS_BLOCK_SIZE - overhead;
|
||||
overhead = block_size - overhead;
|
||||
ret = iso_write(t, buffer, overhead);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Need to align for start of next writer */
|
||||
ret = pad_up_block(t);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -1015,8 +1072,8 @@ static
|
||||
int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
static char buffer[2 * HFSPLUS_BLOCK_SIZE];
|
||||
uint32_t complete_blocks, remaining_blocks;
|
||||
static char buffer[2 * HFSPLUS_MAX_BLOCK_SIZE];
|
||||
uint32_t complete_blocks, remaining_blocks, block_size;
|
||||
int over;
|
||||
Ecma119Image *t;
|
||||
|
||||
@ -1025,28 +1082,29 @@ int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
||||
(double) t->bytes_written);
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
||||
(double) t->bytes_written);
|
||||
#endif
|
||||
|
||||
memset (buffer, -1, sizeof (buffer));
|
||||
complete_blocks = (t->hfsp_allocation_size - 1) / HFSPLUS_BLOCK_SIZE;
|
||||
complete_blocks = (t->hfsp_allocation_size - 1) / block_size;
|
||||
remaining_blocks = t->hfsp_allocation_blocks - complete_blocks;
|
||||
|
||||
while (complete_blocks--)
|
||||
{
|
||||
ret = iso_write(t, buffer, HFSPLUS_BLOCK_SIZE);
|
||||
ret = iso_write(t, buffer, block_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
over = (t->hfsp_allocation_size - 1) % HFSPLUS_BLOCK_SIZE;
|
||||
over = (t->hfsp_allocation_size - 1) % block_size;
|
||||
if (over)
|
||||
{
|
||||
memset (buffer + over, 0, sizeof (buffer) - over);
|
||||
buffer[over] = 0xff00 >> (t->hfsp_total_blocks % 8);
|
||||
ret = iso_write(t, buffer, HFSPLUS_BLOCK_SIZE);
|
||||
ret = iso_write(t, buffer, block_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
remaining_blocks--;
|
||||
@ -1055,29 +1113,32 @@ iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
||||
/* When we have both FAT and HFS+ we may to overestimate needed blocks a bit. */
|
||||
while (remaining_blocks--)
|
||||
{
|
||||
ret = iso_write(t, buffer, HFSPLUS_BLOCK_SIZE);
|
||||
ret = iso_write(t, buffer, block_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef Libisofs_apm_flags_bit2
|
||||
ret = pad_up_block(t);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* ! Libisofs_apm_flags_bit2 */
|
||||
|
||||
iso_msg_debug(t->image->id, "%d written", (int) t->bytes_written);
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer writes sb at = %.f",
|
||||
(double) t->bytes_written);
|
||||
#endif
|
||||
|
||||
ret = write_sb (t);
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer ends at = %.f",
|
||||
(double) t->bytes_written);
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer ends at = %.f",
|
||||
(double) t->bytes_written);
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_apm_flags_bit2
|
||||
ret = pad_up_block(t);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* Libisofs_apm_flags_bit2 */
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
@ -1117,6 +1178,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
IsoNode *pos;
|
||||
IsoDir *dir;
|
||||
int i;
|
||||
uint32_t cat_node_size;
|
||||
|
||||
writer = malloc(sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
@ -1126,6 +1188,12 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
make_hfsplus_decompose_pages();
|
||||
make_hfsplus_class_pages();
|
||||
|
||||
if (target->hfsp_block_size == 0)
|
||||
target->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
|
||||
target->hfsp_cat_node_size = 2 * target->hfsp_block_size;
|
||||
target->hfsp_iso_block_fac = 2048 / target->hfsp_block_size;
|
||||
cat_node_size = target->hfsp_cat_node_size;
|
||||
|
||||
writer->compute_data_blocks = hfsplus_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = nop_writer_write_vol_desc;
|
||||
writer->write_data = hfsplus_writer_write_data;
|
||||
@ -1205,7 +1273,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
{
|
||||
uint32_t last_start = 0;
|
||||
uint32_t i;
|
||||
unsigned bytes_rem = HFSPLUS_CAT_NODE_SIZE - sizeof (struct hfsplus_btnode) - 2;
|
||||
unsigned bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
|
||||
|
||||
target->hfsp_levels[level].nodes = malloc ((target->hfsp_nleafs + 1) * sizeof (target->hfsp_levels[level].nodes[0]));
|
||||
if (!target->hfsp_levels[level].nodes)
|
||||
@ -1231,7 +1299,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
target->hfsp_levels[level].nodes[target->hfsp_levels[level].level_size].parent_id = target->hfsp_leafs[last_start].parent_id;
|
||||
target->hfsp_levels[level].level_size++;
|
||||
last_start = i;
|
||||
bytes_rem = HFSPLUS_CAT_NODE_SIZE - sizeof (struct hfsplus_btnode) - 2;
|
||||
bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
|
||||
}
|
||||
bytes_rem -= target->hfsp_leafs[i].used_size;
|
||||
}
|
||||
@ -1258,7 +1326,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
uint32_t last_start = 0;
|
||||
uint32_t i;
|
||||
uint32_t last_size;
|
||||
unsigned bytes_rem = HFSPLUS_CAT_NODE_SIZE - sizeof (struct hfsplus_btnode) - 2;
|
||||
unsigned bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
|
||||
|
||||
last_size = target->hfsp_levels[level].level_size;
|
||||
|
||||
@ -1283,7 +1351,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
target->hfsp_levels[level].nodes[target->hfsp_levels[level].level_size].parent_id = target->hfsp_levels[level - 1].nodes[last_start].parent_id;
|
||||
target->hfsp_levels[level].level_size++;
|
||||
last_start = i;
|
||||
bytes_rem = HFSPLUS_CAT_NODE_SIZE - sizeof (struct hfsplus_btnode) - 2;
|
||||
bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
|
||||
}
|
||||
bytes_rem -= used_size;
|
||||
}
|
||||
@ -1299,7 +1367,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
|
||||
target->hfsp_nlevels = level + 1;
|
||||
|
||||
if (target->hfsp_nnodes > (HFSPLUS_CAT_NODE_SIZE - 0x100) * 8)
|
||||
if (target->hfsp_nnodes > (cat_node_size - 0x100) * 8)
|
||||
{
|
||||
return iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
|
||||
"HFS+ map nodes aren't implemented");
|
||||
|
@ -1467,6 +1467,27 @@ int iso_write_opts_set_fat(IsoWriteOpts *opts, int enable);
|
||||
int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
|
||||
uint8_t serial_number[8]);
|
||||
|
||||
/**
|
||||
* Set the block size for Apple Partition Map and for HFS+.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param hfsp_block_size
|
||||
* The allocation block size to be used by the HFS+ fileystem.
|
||||
* 0, 512, or 2048
|
||||
* @param hfsp_block_size
|
||||
* The block size to be used for and within the Apple Partition Map.
|
||||
* 0, 512, or 2048.
|
||||
* Size 512 is not compatible with options which produce GPT.
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
*
|
||||
* @since 1.2.4
|
||||
*/
|
||||
int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
|
||||
int hfsp_block_size, int apm_block_size);
|
||||
|
||||
|
||||
/**
|
||||
* Whether to use newer ISO-9660:1999 version.
|
||||
*
|
||||
@ -7343,6 +7364,11 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
|
||||
(FAILURE, HIGH, -390) */
|
||||
#define ISO_BOOT_NO_EFI_ELTO 0xE830FE7A
|
||||
|
||||
/** Not a supported HFS+ or APM block size (FAILURE, HIGH, -391) */
|
||||
#define ISO_BOOT_HFSP_BAD_BSIZE 0xE830FE79
|
||||
|
||||
/** APM block size prevents coexistence with GPT (FAILURE, HIGH, -392) */
|
||||
#define ISO_BOOT_APM_GPT_BSIZE 0xE830FE78
|
||||
|
||||
|
||||
/* Internal developer note:
|
||||
|
@ -289,6 +289,7 @@ iso_write_opts_set_efi_bootp;
|
||||
iso_write_opts_set_fat;
|
||||
iso_write_opts_set_fifo_size;
|
||||
iso_write_opts_set_hardlinks;
|
||||
iso_write_opts_set_hfsp_block_size;
|
||||
iso_write_opts_set_hfsp_serial_number;
|
||||
iso_write_opts_set_hfsplus;
|
||||
iso_write_opts_set_iso1999;
|
||||
|
@ -490,6 +490,10 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Attempt to use an MBR partition entry twice";
|
||||
case ISO_BOOT_NO_EFI_ELTO:
|
||||
return "No suitable El Torito EFI boot image for exposure as GPT partition";
|
||||
case ISO_BOOT_HFSP_BAD_BSIZE:
|
||||
return "Not a supported HFS+ or APM block size";
|
||||
case ISO_BOOT_APM_GPT_BSIZE:
|
||||
return "APM block size prevents coexistence with GPT";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -856,12 +856,11 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
|
||||
uint32_t flags;
|
||||
int block_fac;
|
||||
|
||||
if (flag & 1)
|
||||
if ((flag & 1) || (t->apm_req_flags & 4))
|
||||
block_fac = 1;
|
||||
else
|
||||
block_fac = 2048 / apm_block_size;
|
||||
|
||||
|
||||
memset(buf, apm_block_size, 0);
|
||||
wpt = buf;
|
||||
|
||||
@ -916,9 +915,12 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
|
||||
static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
|
||||
{
|
||||
int i, ret, gap_counter = 0, up_to;
|
||||
uint32_t part_end, goal;
|
||||
uint32_t part_end, goal, block_fac = 1;
|
||||
char gap_name[33];
|
||||
|
||||
if (t->apm_req_flags & 4)
|
||||
block_fac = 2048 / t->apm_block_size;
|
||||
|
||||
/* Find out whether an entry with start_block <= 1 is requested */
|
||||
for (i = 0; i < t->apm_req_count; i++) {
|
||||
if (t->apm_req[i]->start_block <= 1)
|
||||
@ -939,12 +941,12 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
|
||||
if (i < up_to - 1)
|
||||
goal = t->apm_req[i]->start_block;
|
||||
else
|
||||
goal = img_blocks;
|
||||
goal = img_blocks * block_fac;
|
||||
if (i == 1) {
|
||||
/* Description of APM itself */
|
||||
/* Actual APM size is not yet known. Protection begins at PVD */
|
||||
part_end = 16;
|
||||
if (goal < 16 && goal> 1)
|
||||
part_end = 16 * block_fac;
|
||||
if (goal < part_end && goal> 1)
|
||||
part_end = goal;
|
||||
} else {
|
||||
part_end = t->apm_req[i - 1]->start_block +
|
||||
@ -983,45 +985,6 @@ static int rectify_apm(Ecma119Image *t)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (t->apm_req_count == 0)
|
||||
return 1;
|
||||
|
||||
/* These are the only APM block sizes which can be processed here */
|
||||
if (t->apm_block_size > 1536)
|
||||
t->apm_block_size = 2048;
|
||||
else if (t->apm_block_size > 768)
|
||||
t->apm_block_size = 1024;
|
||||
else
|
||||
t->apm_block_size = 512;
|
||||
if (t->gpt_req_count > 0 &&
|
||||
t->apm_block_size != 2048 && t->apm_req_count > 0) {
|
||||
t->apm_block_size = 2048;
|
||||
iso_msgs_submit(0,
|
||||
"GPT and APM requested. Had to force APM Block size to 2048.",
|
||||
0, "DEBUG", 0);
|
||||
}
|
||||
if (t->apm_req_count > 0) {
|
||||
ret = fill_apm_gaps(t, t->curblock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* flag bit0= do not write Block0
|
||||
*/
|
||||
static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
|
||||
int flag)
|
||||
{
|
||||
int i, ret;
|
||||
/* This is a micro mick-up of an APM Block0
|
||||
and also harmless x86 machine code.
|
||||
*/
|
||||
static uint8_t block0_template[8] = {
|
||||
0x45, 0x52, 0x02, 0x00, 0xeb, 0x02, 0xff, 0xff
|
||||
};
|
||||
|
||||
#ifdef NIX
|
||||
/* Disabled */
|
||||
|
||||
@ -1042,6 +1005,42 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
|
||||
}
|
||||
#endif /* NIX */
|
||||
|
||||
if (t->apm_req_count == 0)
|
||||
return 1;
|
||||
|
||||
if (t->gpt_req_count > 0 &&
|
||||
t->apm_block_size != 2048 && t->apm_req_count > 0) {
|
||||
iso_msgs_submit(0,
|
||||
"GPT and APM requested. APM block size would have to be 2048.",
|
||||
0, "FAILURE", 0);
|
||||
return ISO_BOOT_APM_GPT_BSIZE;
|
||||
}
|
||||
if (t->apm_req_count > 0) {
|
||||
ret = fill_apm_gaps(t, t->curblock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* flag bit0= do not write Block0
|
||||
*/
|
||||
static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
|
||||
int flag)
|
||||
{
|
||||
int i, ret;
|
||||
uint32_t block_fac = 1;
|
||||
/* This is a micro mock-up of an APM Block0
|
||||
and also harmless x86 machine code.
|
||||
*/
|
||||
static uint8_t block0_template[8] = {
|
||||
0x45, 0x52, 0x02, 0x00, 0xeb, 0x02, 0xff, 0xff
|
||||
};
|
||||
|
||||
if (t->apm_req_flags & 4)
|
||||
block_fac = 2048 / t->apm_block_size;
|
||||
|
||||
if (t->apm_req_count <= 0)
|
||||
return 2;
|
||||
|
||||
@ -1051,7 +1050,7 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
|
||||
number of APM partitions was determined.
|
||||
*/
|
||||
t->apm_req[t->apm_req_count - 1]->block_count =
|
||||
img_blocks - t->apm_req[t->apm_req_count - 1]->start_block;
|
||||
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]);
|
||||
|
@ -141,7 +141,7 @@ int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot);
|
||||
*/
|
||||
struct iso_apm_partition_request {
|
||||
|
||||
/* Always given in blocks of 2 KiB.
|
||||
/* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4).
|
||||
Written to the ISO image according to Ecma119Image.apm_block_size.
|
||||
*/
|
||||
uint32_t start_block;
|
||||
|
Loading…
Reference in New Issue
Block a user