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)
|
if (target->hfsplus_blessed[i] != NULL)
|
||||||
iso_node_ref(target->hfsplus_blessed[i]);
|
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_count = 0;
|
||||||
target->apm_req_flags = 0;
|
target->apm_req_flags = 0;
|
||||||
for (i = 0; i < ISO_APM_ENTRIES_MAX; i++)
|
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);
|
iso_image_free_checksums(target->image, 0);
|
||||||
image_checksums_mad = 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 */
|
/* ensure the thread is created joinable */
|
||||||
pthread_attr_init(&(target->th_attr));
|
pthread_attr_init(&(target->th_attr));
|
||||||
pthread_attr_setdetachstate(&(target->th_attr), PTHREAD_CREATE_JOINABLE);
|
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;
|
wopts->untranslated_name_len = 0;
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
wopts->hfsp_serial_number[i] = 0;
|
wopts->hfsp_serial_number[i] = 0;
|
||||||
|
wopts->apm_block_size = 0;
|
||||||
|
wopts->hfsp_block_size = 0;
|
||||||
|
|
||||||
*opts = wopts;
|
*opts = wopts;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -3404,3 +3416,17 @@ int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
|
|||||||
return ISO_SUCCESS;
|
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];
|
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;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
@ -819,6 +827,22 @@ struct ecma119_image
|
|||||||
/* See IsoImage and libisofs.h */
|
/* See IsoImage and libisofs.h */
|
||||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
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
|
/* Apple Partition Map description. To be composed during IsoImageWriter
|
||||||
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
||||||
Make sure that the composing writers get registered before the
|
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];
|
struct iso_apm_partition_request *apm_req[ISO_APM_ENTRIES_MAX];
|
||||||
int apm_req_count;
|
int apm_req_count;
|
||||||
/* 512 by default. May be changed to 2048 before writer thread starts. */
|
/* bit1= Do not fill gaps in Apple Partition Map
|
||||||
int apm_block_size;
|
bit2= apm_req entries use apm_block_size in start_block and block_count.
|
||||||
/* bit1= Do not fill gaps in Apple Partition Map */
|
Normally these two parameters are counted in 2 KiB blocks.
|
||||||
|
*/
|
||||||
int apm_req_flags;
|
int apm_req_flags;
|
||||||
|
|
||||||
/* MBR partition table description. To be composed during IsoImageWriter
|
/* MBR partition table description. To be composed during IsoImageWriter
|
||||||
|
@ -20,6 +20,16 @@
|
|||||||
#define Libisofs_ts_debuG yes
|
#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
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
@ -41,10 +51,16 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define HFSPLUS_BLOCK_SIZE 2048
|
/* To be used if Ecma119.hfsplus_block_size == 0 in hfsplus_writer_create().
|
||||||
#define HFSPLUS_CAT_NODE_SIZE (2 * HFSPLUS_BLOCK_SIZE)
|
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>
|
#include <arpa/inet.h>
|
||||||
/* For these prototypes:
|
/* For these prototypes:
|
||||||
@ -417,100 +433,141 @@ cmp_node(const void *f1, const void *f2)
|
|||||||
return ucscmp(a, b);
|
return ucscmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
uint32_t hfsp_size;
|
uint32_t hfsp_size, hfsp_curblock, block_fac, block_size;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
block_size = t->hfsp_block_size;
|
||||||
|
block_fac = t->hfsp_iso_block_fac;
|
||||||
|
|
||||||
#ifdef Libisofs_ts_debuG
|
#ifdef Libisofs_ts_debuG
|
||||||
iso_msg_debug(t->image->id, "hfsplus tail writer start = %.f",
|
iso_msg_debug(t->image->id, "hfsplus tail writer start = %.f",
|
||||||
((double) t->curblock) * 2048.0);
|
((double) t->curblock) * 2048.0);
|
||||||
#endif
|
#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. */
|
/* We need one bit for every block. */
|
||||||
/* So if we allocate x blocks we have to satisfy:
|
/* So if we allocate x blocks we have to satisfy:
|
||||||
8 * HFSPLUS_BLOCK_SIZE * x >= total_size + x
|
8 * block_size * x >= total_size + x
|
||||||
(8 * HFSPLUS_BLOCK_SIZE - 1) * x >= total_size
|
(8 * block_size - 1) * x >= total_size
|
||||||
*/
|
*/
|
||||||
t->hfsp_allocation_blocks = hfsp_size
|
t->hfsp_allocation_blocks = hfsp_size / (8 * block_size - 1) + 1;
|
||||||
/ (8 * HFSPLUS_BLOCK_SIZE - 1) + 1;
|
t->hfsp_allocation_file_start = hfsp_curblock;
|
||||||
t->hfsp_allocation_file_start = t->curblock * HFSPLUS_ISO_BLOCK_FAC;
|
hfsp_curblock += t->hfsp_allocation_blocks;
|
||||||
t->curblock += t->hfsp_allocation_blocks / HFSPLUS_ISO_BLOCK_FAC;
|
|
||||||
if (t->hfsp_allocation_blocks % HFSPLUS_ISO_BLOCK_FAC)
|
#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++;
|
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++;
|
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
|
#ifdef Libisofs_ts_debuG
|
||||||
iso_msg_debug(t->image->id, "hfsplus tail writer end = %.f",
|
iso_msg_debug(t->image->id, "hfsplus tail writer end = %.f",
|
||||||
((double) t->curblock) * 2048.0);
|
((double) hfsp_curblock) * block_size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
t->hfsp_total_blocks = t->curblock * HFSPLUS_ISO_BLOCK_FAC
|
t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start;
|
||||||
- t->hfsp_part_start;
|
|
||||||
t->apm_block_size = HFSPLUS_BLOCK_SIZE;
|
#ifdef Libisofs_hfsplus_no_gap_filL
|
||||||
return iso_quick_apm_entry(t, t->hfsp_part_start / HFSPLUS_ISO_BLOCK_FAC,
|
/* <<< test B20625 : leave out gap filling */
|
||||||
t->hfsp_total_blocks / HFSPLUS_ISO_BLOCK_FAC +
|
t->apm_req_flags |= 2;
|
||||||
!!(t->hfsp_total_blocks % HFSPLUS_ISO_BLOCK_FAC),
|
#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");
|
"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
|
static
|
||||||
int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
Ecma119Image *t;
|
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) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = writer->target;
|
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);
|
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->hfsp_catalog_file_start = hfsp_curblock;
|
||||||
t->curblock += 2 * t->hfsp_nnodes;
|
|
||||||
|
/*
|
||||||
|
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->hfsp_extent_file_start = hfsp_curblock;
|
||||||
t->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;
|
link_blocks = 0;
|
||||||
for (i = 0; i < t->hfsp_nleafs; i++)
|
for (i = 0; i < t->hfsp_nleafs; i++)
|
||||||
if (t->hfsp_leafs[i].unix_type == UNIX_SYMLINK)
|
if (t->hfsp_leafs[i].unix_type == UNIX_SYMLINK)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* ts B20623 : was:
|
t->hfsp_leafs[i].symlink_block = hfsp_curblock;
|
||||||
t->hfsp_leafs[i].symlink_block = t->curblock;
|
hfsp_curblock += (t->hfsp_leafs[i].symlink_size + block_size - 1) / block_size;
|
||||||
t->curblock += (t->hfsp_leafs[i].symlink_size + HFSPLUS_BLOCK_SIZE - 1) / HFSPLUS_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 = hfsp_curblock / block_fac;
|
||||||
t->curblock += link_blocks / HFSPLUS_ISO_BLOCK_FAC;
|
if (hfsp_curblock % block_fac)
|
||||||
if (link_blocks % HFSPLUS_ISO_BLOCK_FAC)
|
|
||||||
t->curblock++;
|
t->curblock++;
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "(a) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes);
|
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;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_time (uint32_t *tm, uint32_t t)
|
static void set_time (uint32_t *tm, uint32_t t)
|
||||||
{
|
{
|
||||||
iso_msb ((uint8_t *) tm, t + 2082844800, 4);
|
iso_msb ((uint8_t *) tm, t + 2082844800, 4);
|
||||||
@ -570,9 +628,12 @@ write_sb (Ecma119Image *t)
|
|||||||
static char buffer[1024];
|
static char buffer[1024];
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
uint32_t block_size;
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Write HFS+ superblock");
|
iso_msg_debug(t->image->id, "Write HFS+ superblock");
|
||||||
|
|
||||||
|
block_size = t->hfsp_block_size;
|
||||||
|
|
||||||
memset (buffer, 0, sizeof (buffer));
|
memset (buffer, 0, sizeof (buffer));
|
||||||
ret = iso_write(t, buffer, 1024);
|
ret = iso_write(t, buffer, 1024);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -592,28 +653,28 @@ write_sb (Ecma119Image *t)
|
|||||||
set_time (&sb.fsck_time, t->now);
|
set_time (&sb.fsck_time, t->now);
|
||||||
iso_msb ((uint8_t *) &sb.file_count, t->hfsp_nfiles, 4);
|
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.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.catalog_node_id, t->hfsp_cat_id, 4);
|
||||||
iso_msb ((uint8_t *) &sb.rsrc_clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
iso_msb ((uint8_t *) &sb.rsrc_clumpsize, block_size, 4);
|
||||||
iso_msb ((uint8_t *) &sb.data_clumpsize, HFSPLUS_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.total_blocks, t->hfsp_total_blocks, 4);
|
||||||
iso_msb ((uint8_t *) &sb.encodings_bitmap + 4, 1, 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.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.clumpsize, 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.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].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.size + 4, block_size, 4);
|
||||||
iso_msb ((uint8_t *) &sb.extents_file.clumpsize, HFSPLUS_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.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].start, t->hfsp_extent_file_start - t->hfsp_part_start, 4);
|
||||||
iso_msb ((uint8_t *) &sb.extents_file.extents[0].count, 1, 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_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.size + 4, 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.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.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].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);
|
iso_msb ((uint8_t *) &sb.catalog_file.extents[0].count, 2 * t->hfsp_nnodes, 4);
|
||||||
@ -642,18 +703,21 @@ static
|
|||||||
int hfsplus_writer_write_data(IsoImageWriter *writer)
|
int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
static char buffer[2 * HFSPLUS_BLOCK_SIZE];
|
static char buffer[2 * HFSPLUS_MAX_BLOCK_SIZE];
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
struct hfsplus_btnode *node_head;
|
struct hfsplus_btnode *node_head;
|
||||||
struct hfsplus_btheader *tree_head;
|
struct hfsplus_btheader *tree_head;
|
||||||
int level;
|
int level;
|
||||||
uint32_t curpos = 1, i;
|
uint32_t curpos = 1, i, block_fac, cat_node_size, block_size;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = writer->target;
|
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);
|
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->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->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->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->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->total_nodes, t->hfsp_nnodes, 4);
|
||||||
iso_msb ((uint8_t *) &tree_head->free_nodes, 0, 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;
|
tree_head->key_compare = 0xcf;
|
||||||
iso_msb ((uint8_t *) &tree_head->attributes, 2 | 4, 4);
|
iso_msb ((uint8_t *) &tree_head->attributes, 2 | 4, 4);
|
||||||
memset (buffer + 0xf8, -1, t->hfsp_nnodes / 8);
|
memset (buffer + 0xf8, -1, t->hfsp_nnodes / 8);
|
||||||
buffer[0xf8 + (t->hfsp_nnodes / 8)] = 0xff00 >> (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[cat_node_size - 1] = sizeof (*node_head);
|
||||||
buffer[HFSPLUS_CAT_NODE_SIZE - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
buffer[cat_node_size - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
||||||
buffer[HFSPLUS_CAT_NODE_SIZE - 5] = (char) 0xf8;
|
buffer[cat_node_size - 5] = (char) 0xf8;
|
||||||
buffer[HFSPLUS_CAT_NODE_SIZE - 7] = (char) ((HFSPLUS_CAT_NODE_SIZE - 8) & 0xff);
|
buffer[cat_node_size - 7] = (char) ((cat_node_size - 8) & 0xff);
|
||||||
buffer[HFSPLUS_CAT_NODE_SIZE - 8] = (HFSPLUS_CAT_NODE_SIZE - 8) >> 8;
|
buffer[cat_node_size - 8] = (cat_node_size - 8) >> 8;
|
||||||
|
|
||||||
#ifdef Libisofs_hfsplus_verbose_debuG
|
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||||
iso_msg_debug(t->image->id, "Write\n");
|
iso_msg_debug(t->image->id, "Write\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = iso_write(t, buffer, HFSPLUS_CAT_NODE_SIZE);
|
ret = iso_write(t, buffer, cat_node_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -720,7 +784,7 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
|||||||
curoff = sizeof (struct hfsplus_btnode);
|
curoff = sizeof (struct hfsplus_btnode);
|
||||||
for (j = 0; j < t->hfsp_levels[level].nodes[i].cnt; j++)
|
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].strlen + 6, 2);
|
||||||
iso_msb ((uint8_t *) buffer + curoff + 2, t->hfsp_levels[level - 1].nodes[curnode].parent_id, 4);
|
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;
|
curoff += 4;
|
||||||
curnode++;
|
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
|
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||||
iso_msg_debug(t->image->id, "Write\n");
|
iso_msg_debug(t->image->id, "Write\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = iso_write(t, buffer, HFSPLUS_CAT_NODE_SIZE);
|
ret = iso_write(t, buffer, cat_node_size);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -766,7 +830,7 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
|||||||
curoff = sizeof (struct hfsplus_btnode);
|
curoff = sizeof (struct hfsplus_btnode);
|
||||||
for (j = 0; j < t->hfsp_levels[level].nodes[i].cnt; j++)
|
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
|
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||||
|
|
||||||
@ -920,16 +984,16 @@ iso_msg_debug(t->image->id,
|
|||||||
&blk, &sz);
|
&blk, &sz);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
blk *= HFSPLUS_ISO_BLOCK_FAC;
|
blk *= block_fac;
|
||||||
}
|
}
|
||||||
if (sz == 0)
|
if (sz == 0)
|
||||||
blk = t->hfsp_part_start;
|
blk = t->hfsp_part_start;
|
||||||
iso_msb ((uint8_t *) &data_fork->size, sz >> 32, 4);
|
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->size + 4, sz, 4);
|
||||||
iso_msb ((uint8_t *) &data_fork->clumpsize, HFSPLUS_BLOCK_SIZE, 4);
|
iso_msb ((uint8_t *) &data_fork->clumpsize, 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->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].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;
|
curoff += sizeof (*data_fork) * 2;
|
||||||
/* FIXME: resource fork */
|
/* FIXME: resource fork */
|
||||||
@ -939,13 +1003,13 @@ iso_msg_debug(t->image->id,
|
|||||||
}
|
}
|
||||||
curnode++;
|
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
|
#ifdef Libisofs_hfsplus_verbose_debuG
|
||||||
iso_msg_debug(t->image->id, "Write\n");
|
iso_msg_debug(t->image->id, "Write\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = iso_write(t, buffer, HFSPLUS_CAT_NODE_SIZE);
|
ret = iso_write(t, buffer, cat_node_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -953,35 +1017,27 @@ iso_msg_debug(t->image->id,
|
|||||||
}
|
}
|
||||||
memset (buffer, 0, sizeof (buffer));
|
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);
|
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 = (struct hfsplus_btnode *) buffer;
|
||||||
node_head->type = 1;
|
node_head->type = 1;
|
||||||
iso_msb ((uint8_t *) &node_head->count, 3, 2);
|
iso_msb ((uint8_t *) &node_head->count, 3, 2);
|
||||||
tree_head = (struct hfsplus_btheader *) (node_head + 1);
|
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->keysize, 10, 2);
|
||||||
iso_msb ((uint8_t *) &tree_head->total_nodes, 1, 4);
|
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->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);
|
iso_msb ((uint8_t *) &tree_head->attributes, 2, 4);
|
||||||
buffer[0xf8] = (char) 0x80;
|
buffer[0xf8] = (char) 0x80;
|
||||||
|
|
||||||
buffer[HFSPLUS_BLOCK_SIZE - 1] = sizeof (*node_head);
|
buffer[block_size - 1] = sizeof (*node_head);
|
||||||
buffer[HFSPLUS_BLOCK_SIZE - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
buffer[block_size - 3] = sizeof (*node_head) + sizeof (*tree_head);
|
||||||
buffer[HFSPLUS_BLOCK_SIZE - 5] = (char) 0xf8;
|
buffer[block_size - 5] = (char) 0xf8;
|
||||||
buffer[HFSPLUS_BLOCK_SIZE - 7] = (char) ((HFSPLUS_BLOCK_SIZE - 8) & 0xff);
|
buffer[block_size - 7] = (char) ((block_size - 8) & 0xff);
|
||||||
buffer[HFSPLUS_BLOCK_SIZE - 8] = (HFSPLUS_BLOCK_SIZE - 8) >> 8;
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -995,14 +1051,15 @@ iso_msg_debug(t->image->id,
|
|||||||
ret = iso_write(t, sym->dest, t->hfsp_leafs[i].symlink_size);
|
ret = iso_write(t, sym->dest, t->hfsp_leafs[i].symlink_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
overhead = t->hfsp_leafs[i].symlink_size % HFSPLUS_BLOCK_SIZE;
|
overhead = t->hfsp_leafs[i].symlink_size % block_size;
|
||||||
if (overhead)
|
if (overhead)
|
||||||
overhead = HFSPLUS_BLOCK_SIZE - overhead;
|
overhead = block_size - overhead;
|
||||||
ret = iso_write(t, buffer, overhead);
|
ret = iso_write(t, buffer, overhead);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Need to align for start of next writer */
|
||||||
ret = pad_up_block(t);
|
ret = pad_up_block(t);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1015,8 +1072,8 @@ static
|
|||||||
int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
|
int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
static char buffer[2 * HFSPLUS_BLOCK_SIZE];
|
static char buffer[2 * HFSPLUS_MAX_BLOCK_SIZE];
|
||||||
uint32_t complete_blocks, remaining_blocks;
|
uint32_t complete_blocks, remaining_blocks, block_size;
|
||||||
int over;
|
int over;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
|
|
||||||
@ -1025,6 +1082,7 @@ int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
block_size = t->hfsp_block_size;
|
||||||
|
|
||||||
#ifdef Libisofs_ts_debuG
|
#ifdef Libisofs_ts_debuG
|
||||||
iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
||||||
@ -1032,21 +1090,21 @@ iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset (buffer, -1, sizeof (buffer));
|
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;
|
remaining_blocks = t->hfsp_allocation_blocks - complete_blocks;
|
||||||
|
|
||||||
while (complete_blocks--)
|
while (complete_blocks--)
|
||||||
{
|
{
|
||||||
ret = iso_write(t, buffer, HFSPLUS_BLOCK_SIZE);
|
ret = iso_write(t, buffer, block_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
over = (t->hfsp_allocation_size - 1) % HFSPLUS_BLOCK_SIZE;
|
over = (t->hfsp_allocation_size - 1) % block_size;
|
||||||
if (over)
|
if (over)
|
||||||
{
|
{
|
||||||
memset (buffer + over, 0, sizeof (buffer) - over);
|
memset (buffer + over, 0, sizeof (buffer) - over);
|
||||||
buffer[over] = 0xff00 >> (t->hfsp_total_blocks % 8);
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
remaining_blocks--;
|
remaining_blocks--;
|
||||||
@ -1055,22 +1113,19 @@ 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. */
|
/* When we have both FAT and HFS+ we may to overestimate needed blocks a bit. */
|
||||||
while (remaining_blocks--)
|
while (remaining_blocks--)
|
||||||
{
|
{
|
||||||
ret = iso_write(t, buffer, HFSPLUS_BLOCK_SIZE);
|
ret = iso_write(t, buffer, block_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef Libisofs_apm_flags_bit2
|
||||||
ret = pad_up_block(t);
|
ret = pad_up_block(t);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif /* ! Libisofs_apm_flags_bit2 */
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "%d written", (int) t->bytes_written);
|
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);
|
ret = write_sb (t);
|
||||||
|
|
||||||
#ifdef Libisofs_ts_debuG
|
#ifdef Libisofs_ts_debuG
|
||||||
@ -1078,6 +1133,12 @@ iso_msg_debug(t->image->id, "hfsplus tail writer ends at = %.f",
|
|||||||
(double) t->bytes_written);
|
(double) t->bytes_written);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Libisofs_apm_flags_bit2
|
||||||
|
ret = pad_up_block(t);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#endif /* Libisofs_apm_flags_bit2 */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1117,6 +1178,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
IsoNode *pos;
|
IsoNode *pos;
|
||||||
IsoDir *dir;
|
IsoDir *dir;
|
||||||
int i;
|
int i;
|
||||||
|
uint32_t cat_node_size;
|
||||||
|
|
||||||
writer = malloc(sizeof(IsoImageWriter));
|
writer = malloc(sizeof(IsoImageWriter));
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
@ -1126,6 +1188,12 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
make_hfsplus_decompose_pages();
|
make_hfsplus_decompose_pages();
|
||||||
make_hfsplus_class_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->compute_data_blocks = hfsplus_writer_compute_data_blocks;
|
||||||
writer->write_vol_desc = nop_writer_write_vol_desc;
|
writer->write_vol_desc = nop_writer_write_vol_desc;
|
||||||
writer->write_data = hfsplus_writer_write_data;
|
writer->write_data = hfsplus_writer_write_data;
|
||||||
@ -1205,7 +1273,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
{
|
{
|
||||||
uint32_t last_start = 0;
|
uint32_t last_start = 0;
|
||||||
uint32_t i;
|
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]));
|
target->hfsp_levels[level].nodes = malloc ((target->hfsp_nleafs + 1) * sizeof (target->hfsp_levels[level].nodes[0]));
|
||||||
if (!target->hfsp_levels[level].nodes)
|
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].nodes[target->hfsp_levels[level].level_size].parent_id = target->hfsp_leafs[last_start].parent_id;
|
||||||
target->hfsp_levels[level].level_size++;
|
target->hfsp_levels[level].level_size++;
|
||||||
last_start = i;
|
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;
|
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 last_start = 0;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t last_size;
|
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;
|
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].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++;
|
target->hfsp_levels[level].level_size++;
|
||||||
last_start = i;
|
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;
|
bytes_rem -= used_size;
|
||||||
}
|
}
|
||||||
@ -1299,7 +1367,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
target->hfsp_nlevels = level + 1;
|
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,
|
return iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
|
||||||
"HFS+ map nodes aren't implemented");
|
"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,
|
int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
|
||||||
uint8_t serial_number[8]);
|
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.
|
* 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) */
|
(FAILURE, HIGH, -390) */
|
||||||
#define ISO_BOOT_NO_EFI_ELTO 0xE830FE7A
|
#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:
|
/* Internal developer note:
|
||||||
|
@ -289,6 +289,7 @@ iso_write_opts_set_efi_bootp;
|
|||||||
iso_write_opts_set_fat;
|
iso_write_opts_set_fat;
|
||||||
iso_write_opts_set_fifo_size;
|
iso_write_opts_set_fifo_size;
|
||||||
iso_write_opts_set_hardlinks;
|
iso_write_opts_set_hardlinks;
|
||||||
|
iso_write_opts_set_hfsp_block_size;
|
||||||
iso_write_opts_set_hfsp_serial_number;
|
iso_write_opts_set_hfsp_serial_number;
|
||||||
iso_write_opts_set_hfsplus;
|
iso_write_opts_set_hfsplus;
|
||||||
iso_write_opts_set_iso1999;
|
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";
|
return "Attempt to use an MBR partition entry twice";
|
||||||
case ISO_BOOT_NO_EFI_ELTO:
|
case ISO_BOOT_NO_EFI_ELTO:
|
||||||
return "No suitable El Torito EFI boot image for exposure as GPT partition";
|
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:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -856,12 +856,11 @@ static int iso_write_apm_entry(Ecma119Image *t, int apm_block_size,
|
|||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
int block_fac;
|
int block_fac;
|
||||||
|
|
||||||
if (flag & 1)
|
if ((flag & 1) || (t->apm_req_flags & 4))
|
||||||
block_fac = 1;
|
block_fac = 1;
|
||||||
else
|
else
|
||||||
block_fac = 2048 / apm_block_size;
|
block_fac = 2048 / apm_block_size;
|
||||||
|
|
||||||
|
|
||||||
memset(buf, apm_block_size, 0);
|
memset(buf, apm_block_size, 0);
|
||||||
wpt = buf;
|
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)
|
static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
|
||||||
{
|
{
|
||||||
int i, ret, gap_counter = 0, up_to;
|
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];
|
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 */
|
/* Find out whether an entry with start_block <= 1 is requested */
|
||||||
for (i = 0; i < t->apm_req_count; i++) {
|
for (i = 0; i < t->apm_req_count; i++) {
|
||||||
if (t->apm_req[i]->start_block <= 1)
|
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)
|
if (i < up_to - 1)
|
||||||
goal = t->apm_req[i]->start_block;
|
goal = t->apm_req[i]->start_block;
|
||||||
else
|
else
|
||||||
goal = img_blocks;
|
goal = img_blocks * block_fac;
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
/* Description of APM itself */
|
/* Description of APM itself */
|
||||||
/* Actual APM size is not yet known. Protection begins at PVD */
|
/* Actual APM size is not yet known. Protection begins at PVD */
|
||||||
part_end = 16;
|
part_end = 16 * block_fac;
|
||||||
if (goal < 16 && goal> 1)
|
if (goal < part_end && goal> 1)
|
||||||
part_end = goal;
|
part_end = goal;
|
||||||
} else {
|
} else {
|
||||||
part_end = t->apm_req[i - 1]->start_block +
|
part_end = t->apm_req[i - 1]->start_block +
|
||||||
@ -983,45 +985,6 @@ static int rectify_apm(Ecma119Image *t)
|
|||||||
{
|
{
|
||||||
int ret;
|
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
|
#ifdef NIX
|
||||||
/* Disabled */
|
/* Disabled */
|
||||||
|
|
||||||
@ -1042,6 +1005,42 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
|
|||||||
}
|
}
|
||||||
#endif /* NIX */
|
#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)
|
if (t->apm_req_count <= 0)
|
||||||
return 2;
|
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.
|
number of APM partitions was determined.
|
||||||
*/
|
*/
|
||||||
t->apm_req[t->apm_req_count - 1]->block_count =
|
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 it is still empty, remove it */
|
||||||
if(t->apm_req[t->apm_req_count - 1]->block_count == 0) {
|
if(t->apm_req[t->apm_req_count - 1]->block_count == 0) {
|
||||||
free(t->apm_req[t->apm_req_count - 1]);
|
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 {
|
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.
|
Written to the ISO image according to Ecma119Image.apm_block_size.
|
||||||
*/
|
*/
|
||||||
uint32_t start_block;
|
uint32_t start_block;
|
||||||
|
Loading…
Reference in New Issue
Block a user