New API function iso_write_opts_set_part_offset() controls creation of
an MBR with a first partiton table entry that bears non-zero start address. A second set of volume descriptors and directory tree+tables gets created which can be used to mount the image at the partition start. Not yet implemented for second set: ISO 9660:1999, MD5 checksums.
This commit is contained in:
parent
95121e2f9f
commit
017dcb39f2
@ -293,7 +293,51 @@ unsigned int iso_ring_buffer_get_times_empty(IsoRingBuffer *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/** Internal via buffer.h
|
||||||
|
*
|
||||||
|
* Get the status of a ring buffer.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* The ring buffer object to inquire
|
||||||
|
* @param size
|
||||||
|
* Will be filled with the total size of the buffer, in bytes
|
||||||
|
* @param free_bytes
|
||||||
|
* Will be filled with the bytes currently available in buffer
|
||||||
|
* @return
|
||||||
|
* < 0 error, > 0 state:
|
||||||
|
* 1="active" : input and consumption are active
|
||||||
|
* 2="ending" : input has ended without error
|
||||||
|
* 3="failing" : input had error and ended,
|
||||||
|
* 5="abandoned" : consumption has ended prematurely
|
||||||
|
* 6="ended" : consumption has ended without input error
|
||||||
|
* 7="aborted" : consumption has ended after input error
|
||||||
|
*/
|
||||||
|
int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
|
||||||
|
size_t *free_bytes)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get mutex */
|
||||||
|
pthread_mutex_lock(&buf->mutex);
|
||||||
|
if (size) {
|
||||||
|
*size = buf->cap;
|
||||||
|
}
|
||||||
|
if (free_bytes) {
|
||||||
|
*free_bytes = buf->cap - buf->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (buf->rend ? 4 : 0) + (buf->wend + 1);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&buf->mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** API via libisofs.h
|
||||||
|
*
|
||||||
* Get the status of the buffer used by a burn_source.
|
* Get the status of the buffer used by a burn_source.
|
||||||
*
|
*
|
||||||
* @param b
|
* @param b
|
||||||
@ -321,18 +365,7 @@ int iso_ring_buffer_get_status(struct burn_source *b, size_t *size,
|
|||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
buf = ((Ecma119Image*)(b->data))->buffer;
|
buf = ((Ecma119Image*)(b->data))->buffer;
|
||||||
|
ret = iso_ring_buffer_get_buf_status(buf, size, free_bytes);
|
||||||
/* get mutex */
|
|
||||||
pthread_mutex_lock(&buf->mutex);
|
|
||||||
if (size) {
|
|
||||||
*size = buf->cap;
|
|
||||||
}
|
|
||||||
if (free_bytes) {
|
|
||||||
*free_bytes = buf->cap - buf->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = (buf->rend ? 4 : 0) + (buf->wend + 1);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&buf->mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,28 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count);
|
|||||||
*/
|
*/
|
||||||
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count);
|
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count);
|
||||||
|
|
||||||
|
/** Backend of API call iso_ring_buffer_get_status()
|
||||||
|
*
|
||||||
|
* Get the status of a ring buffer.
|
||||||
|
*
|
||||||
|
* @param buf
|
||||||
|
* The ring buffer object to inquire
|
||||||
|
* @param size
|
||||||
|
* Will be filled with the total size of the buffer, in bytes
|
||||||
|
* @param free_bytes
|
||||||
|
* Will be filled with the bytes currently available in buffer
|
||||||
|
* @return
|
||||||
|
* < 0 error, > 0 state:
|
||||||
|
* 1="active" : input and consumption are active
|
||||||
|
* 2="ending" : input has ended without error
|
||||||
|
* 3="failing" : input had error and ended,
|
||||||
|
* 5="abandoned" : consumption has ended prematurely
|
||||||
|
* 6="ended" : consumption has ended without input error
|
||||||
|
* 7="aborted" : consumption has ended after input error
|
||||||
|
*/
|
||||||
|
int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
|
||||||
|
size_t *free_bytes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the buffer (to be called by the writer).
|
* Close the buffer (to be called by the writer).
|
||||||
* You have to explicity close the buffer when you don't have more data to
|
* You have to explicity close the buffer when you don't have more data to
|
||||||
|
@ -85,6 +85,9 @@ void ecma119_image_free(Ecma119Image *t)
|
|||||||
free(t->checksum_buffer);
|
free(t->checksum_buffer);
|
||||||
if (t->writers != NULL)
|
if (t->writers != NULL)
|
||||||
free(t->writers);
|
free(t->writers);
|
||||||
|
if (t->partition_root != NULL)
|
||||||
|
ecma119_node_free(t->partition_root);
|
||||||
|
t->partition_root = NULL;
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,6 +234,7 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
{
|
{
|
||||||
Ecma119Image *target;
|
Ecma119Image *target;
|
||||||
uint32_t path_table_size;
|
uint32_t path_table_size;
|
||||||
|
size_t ndirs;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
@ -253,6 +257,25 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
target->m_path_table_pos = target->curblock;
|
target->m_path_table_pos = target->curblock;
|
||||||
target->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
target->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
target->path_table_size = path_table_size;
|
target->path_table_size = path_table_size;
|
||||||
|
|
||||||
|
if (target->partition_offset > 0) {
|
||||||
|
/* TWINTREE: take into respect second directory tree */
|
||||||
|
ndirs = target->ndirs;
|
||||||
|
target->ndirs = 0;
|
||||||
|
calc_dir_pos(target, target->partition_root);
|
||||||
|
if (target->ndirs != ndirs) {
|
||||||
|
iso_msg_submit(target->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
|
"Number of directories differs in ECMA-119 partiton_tree");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
/* TWINTREE: take into respect second set of path tables */
|
||||||
|
path_table_size = calc_path_table_size(target->partition_root);
|
||||||
|
target->partition_l_table_pos = target->curblock;
|
||||||
|
target->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
|
target->partition_m_table_pos = target->curblock;
|
||||||
|
target->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if (target->md5_session_checksum) {
|
if (target->md5_session_checksum) {
|
||||||
/* Account for tree checksum tag */
|
/* Account for tree checksum tag */
|
||||||
target->checksum_tree_tag_pos = target->curblock;
|
target->checksum_tree_tag_pos = target->curblock;
|
||||||
@ -323,7 +346,8 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
|||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
|
||||||
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
||||||
iso_bb(rec->block, block, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
if (t->dir_rec_mtime) {
|
if (t->dir_rec_mtime) {
|
||||||
iso= node->node;
|
iso= node->node;
|
||||||
@ -411,15 +435,29 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
vol.vol_desc_version[0] = 1;
|
vol.vol_desc_version[0] = 1;
|
||||||
strncpy_pad((char*)vol.system_id, system_id, 32);
|
strncpy_pad((char*)vol.system_id, system_id, 32);
|
||||||
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
||||||
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
|
|
||||||
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
|
||||||
|
4);
|
||||||
|
|
||||||
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
||||||
iso_bb(vol.path_table_size, t->path_table_size, 4);
|
iso_bb(vol.path_table_size, t->path_table_size, 4);
|
||||||
|
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
/* TWINTREE: point to second tables and second root */
|
||||||
|
iso_lsb(vol.l_path_table_pos,
|
||||||
|
t->partition_l_table_pos - t->eff_partition_offset, 4);
|
||||||
|
iso_msb(vol.m_path_table_pos,
|
||||||
|
t->partition_m_table_pos - t->eff_partition_offset, 4);
|
||||||
|
write_one_dir_record(t, t->partition_root, 0,
|
||||||
|
vol.root_dir_record, 1, NULL, 0);
|
||||||
|
} else {
|
||||||
iso_lsb(vol.l_path_table_pos, t->l_path_table_pos, 4);
|
iso_lsb(vol.l_path_table_pos, t->l_path_table_pos, 4);
|
||||||
iso_msb(vol.m_path_table_pos, t->m_path_table_pos, 4);
|
iso_msb(vol.m_path_table_pos, t->m_path_table_pos, 4);
|
||||||
|
|
||||||
write_one_dir_record(t, t->root, 0, vol.root_dir_record, 1, NULL, 0);
|
write_one_dir_record(t, t->root, 0, vol.root_dir_record, 1, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
strncpy_pad((char*)vol.vol_set_id, volset_id, 128);
|
strncpy_pad((char*)vol.vol_set_id, volset_id, 128);
|
||||||
strncpy_pad((char*)vol.publisher_id, pub_id, 128);
|
strncpy_pad((char*)vol.publisher_id, pub_id, 128);
|
||||||
@ -637,7 +675,9 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
|||||||
rec = (struct ecma119_path_table_record*) buf;
|
rec = (struct ecma119_path_table_record*) buf;
|
||||||
rec->len_di[0] = dir->parent ? (uint8_t) strlen(dir->iso_name) : 1;
|
rec->len_di[0] = dir->parent ? (uint8_t) strlen(dir->iso_name) : 1;
|
||||||
rec->len_xa[0] = 0;
|
rec->len_xa[0] = 0;
|
||||||
write_int(rec->block, dir->info.dir->block, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
write_int(rec->block, dir->info.dir->block - t->eff_partition_offset,
|
||||||
|
4);
|
||||||
write_int(rec->parent, parent + 1, 2);
|
write_int(rec->parent, parent + 1, 2);
|
||||||
if (dir->parent) {
|
if (dir->parent) {
|
||||||
memcpy(rec->dir_id, dir->iso_name, rec->len_di[0]);
|
memcpy(rec->dir_id, dir->iso_name, rec->len_di[0]);
|
||||||
@ -676,7 +716,13 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
if (pathlist == NULL) {
|
if (pathlist == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TWINTREE: t->partition_root */
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
pathlist[0] = t->partition_root;
|
||||||
|
} else {
|
||||||
pathlist[0] = t->root;
|
pathlist[0] = t->root;
|
||||||
|
}
|
||||||
cur = 1;
|
cur = 1;
|
||||||
|
|
||||||
for (i = 0; i < t->ndirs; i++) {
|
for (i = 0; i < t->ndirs; i++) {
|
||||||
@ -703,11 +749,54 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write both the directory structure (ECMA-119, 6.8) and the L and M
|
* Write the directory structure (ECMA-119, 6.8) and the L and M
|
||||||
* Path Tables (ECMA-119, 6.9).
|
* Path Tables (ECMA-119, 6.9).
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
|
int ecma119_writer_write_dirs(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Image *t;
|
||||||
|
Ecma119Node *root;
|
||||||
|
|
||||||
|
t = writer->target;
|
||||||
|
|
||||||
|
/* first of all, we write the directory structure */
|
||||||
|
/* TWINTREE: t->root -> root */
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
root = t->partition_root;
|
||||||
|
} else {
|
||||||
|
root = t->root;
|
||||||
|
}
|
||||||
|
ret = write_dirs(t, root, root);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and write the path tables */
|
||||||
|
ret = write_path_tables(t);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (t->md5_session_checksum) {
|
||||||
|
/* Write tree checksum tag */
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
/* >>> TWINTREE: >>> For now, checksums and tags are only for the
|
||||||
|
first session */;
|
||||||
|
} else {
|
||||||
|
ret = iso_md5_write_tag(t, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write directory structure and Path Tables of the ECMA-119 tree.
|
||||||
|
* This happens eventually a second time for the duplicates which use
|
||||||
|
* addresses with partition offset.
|
||||||
|
*/
|
||||||
|
static
|
||||||
int ecma119_writer_write_data(IsoImageWriter *writer)
|
int ecma119_writer_write_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -718,22 +807,20 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
/* first of all, we write the directory structure */
|
ret = ecma119_writer_write_dirs(writer);
|
||||||
ret = write_dirs(t, t->root, t->root);
|
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* and write the path tables */
|
|
||||||
ret = write_path_tables(t);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (t->md5_session_checksum) {
|
|
||||||
/* Write tree checksum tag */
|
if (t->partition_offset > 0) {
|
||||||
ret = iso_md5_write_tag(t, 3);
|
/* TWINTREE: */
|
||||||
}
|
t->eff_partition_offset = t->partition_offset;
|
||||||
|
ret = ecma119_writer_write_dirs(writer);
|
||||||
|
t->eff_partition_offset = 0;
|
||||||
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int ecma119_writer_free_data(IsoImageWriter *writer)
|
int ecma119_writer_free_data(IsoImageWriter *writer)
|
||||||
@ -768,6 +855,16 @@ int ecma119_writer_create(Ecma119Image *target)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TWINTREE: */
|
||||||
|
if(target->partition_offset > 0) {
|
||||||
|
/* Create second tree */
|
||||||
|
target->eff_partition_offset = target->partition_offset;
|
||||||
|
ret = ecma119_tree_create(target);
|
||||||
|
target->eff_partition_offset = 0;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* we need the volume descriptor */
|
/* we need the volume descriptor */
|
||||||
target->curblock++;
|
target->curblock++;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -867,12 +964,157 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int write_vol_desc_terminator(Ecma119Image *target)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
uint8_t buf[BLOCK_SIZE];
|
||||||
|
struct ecma119_vol_desc_terminator *vol;
|
||||||
|
|
||||||
|
vol = (struct ecma119_vol_desc_terminator *) buf;
|
||||||
|
|
||||||
|
vol->vol_desc_type[0] = 255;
|
||||||
|
memcpy(vol->std_identifier, "CD001", 5);
|
||||||
|
vol->vol_desc_version[0] = 1;
|
||||||
|
|
||||||
|
res = iso_write(target, buf, BLOCK_SIZE);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= initialize system area by target->opts_overwrite
|
||||||
|
bit1= fifo is not yet draining. Inquire write_count from fifo.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
||||||
|
{
|
||||||
|
int res, i;
|
||||||
|
uint8_t sa[16 * BLOCK_SIZE];
|
||||||
|
IsoImageWriter *writer;
|
||||||
|
size_t buffer_size = 0, buffer_free = 0, buffer_start_free = 0;
|
||||||
|
|
||||||
|
iso_ring_buffer_get_buf_status(target->buffer, &buffer_size,
|
||||||
|
&buffer_start_free);
|
||||||
|
*write_count = 0;
|
||||||
|
/* Write System Area (ECMA-119, 6.2.1) */
|
||||||
|
if ((flag & 1) && target->opts_overwrite != NULL)
|
||||||
|
memcpy(sa, target->opts_overwrite, 16 * BLOCK_SIZE);
|
||||||
|
res = iso_write_system_area(target, sa);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
res = iso_write(target, sa, 16 * BLOCK_SIZE);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
*write_count = 16;
|
||||||
|
|
||||||
|
/* write volume descriptors, one per writer */
|
||||||
|
iso_msg_debug(target->image->id, "Write volume descriptors");
|
||||||
|
for (i = 0; i < target->nwriters; ++i) {
|
||||||
|
writer = target->writers[i];
|
||||||
|
res = writer->write_vol_desc(writer);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write Volume Descriptor Set Terminator (ECMA-119, 8.3) */
|
||||||
|
res = write_vol_desc_terminator(target);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
|
||||||
|
if(flag & 2) {
|
||||||
|
iso_ring_buffer_get_buf_status(target->buffer, &buffer_size,
|
||||||
|
&buffer_free);
|
||||||
|
*write_count = ( buffer_start_free - buffer_free ) / BLOCK_SIZE;
|
||||||
|
} else {
|
||||||
|
*write_count = target->bytes_written / BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
write_error:;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||||
|
{
|
||||||
|
int res, i;
|
||||||
|
uint8_t buf[BLOCK_SIZE];
|
||||||
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
|
if (target->partition_offset <= 0)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
/* TWINTREE: write padding up to target->partition_offset + 16 */
|
||||||
|
memset(buf, 0, 2048);
|
||||||
|
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
|
||||||
|
res = iso_write(target, buf, BLOCK_SIZE);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TWINTREE: write volume descriptors subtracting
|
||||||
|
target->partiton_offset from any LBA pointer.
|
||||||
|
*/
|
||||||
|
target->eff_partition_offset = target->partition_offset;
|
||||||
|
for (i = 0; i < target->nwriters; ++i) {
|
||||||
|
writer = target->writers[i];
|
||||||
|
/* TWINTREE:
|
||||||
|
Not all writers have an entry in the partion volume descriptor set.
|
||||||
|
It must be guaranteed that they write exactly one block.
|
||||||
|
*/
|
||||||
|
/* >>> TWINTREE: Enhance ISO1999 writer and add it here */
|
||||||
|
if(writer->write_vol_desc != ecma119_writer_write_vol_desc &&
|
||||||
|
writer->write_vol_desc != joliet_writer_write_vol_desc)
|
||||||
|
continue;
|
||||||
|
res = writer->write_vol_desc(writer);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
(*write_count)++;
|
||||||
|
}
|
||||||
|
res = write_vol_desc_terminator(target);
|
||||||
|
if (res < 0)
|
||||||
|
goto write_error;
|
||||||
|
(*write_count)++;
|
||||||
|
target->eff_partition_offset = 0;
|
||||||
|
|
||||||
|
/* >>> TWINTREE: Postponed for now:
|
||||||
|
Write second superblock checksum tag */;
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
write_error:;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int write_head_part(Ecma119Image *target, int flag)
|
||||||
|
{
|
||||||
|
int res, write_count = 0;
|
||||||
|
|
||||||
|
/* System area and volume descriptors */
|
||||||
|
res = write_head_part1(target, &write_count, 0);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
/* Write superblock checksum tag */
|
||||||
|
if (target->md5_session_checksum && target->checksum_ctx != NULL) {
|
||||||
|
res = iso_md5_write_tag(target, 2);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
write_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second set of system area and volume descriptors for partition_offset */
|
||||||
|
res = write_head_part2(target, &write_count, 0);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void *write_function(void *arg)
|
void *write_function(void *arg)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
size_t i;
|
size_t i;
|
||||||
uint8_t buf[BLOCK_SIZE];
|
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
Ecma119Image *target = (Ecma119Image*)arg;
|
Ecma119Image *target = (Ecma119Image*)arg;
|
||||||
@ -881,50 +1123,9 @@ void *write_function(void *arg)
|
|||||||
target->bytes_written = (off_t) 0;
|
target->bytes_written = (off_t) 0;
|
||||||
target->percent_written = 0;
|
target->percent_written = 0;
|
||||||
|
|
||||||
/* Write System Area (ECMA-119, 6.2.1) */
|
res = write_head_part(target, 0);
|
||||||
{
|
|
||||||
uint8_t sa[16 * BLOCK_SIZE];
|
|
||||||
res = iso_write_system_area(target, sa);
|
|
||||||
if (res < 0) {
|
|
||||||
goto write_error;
|
|
||||||
}
|
|
||||||
res = iso_write(target, sa, 16 * BLOCK_SIZE);
|
|
||||||
if (res < 0) {
|
|
||||||
goto write_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write volume descriptors, one per writer */
|
|
||||||
iso_msg_debug(target->image->id, "Write volume descriptors");
|
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
|
||||||
writer = target->writers[i];
|
|
||||||
res = writer->write_vol_desc(writer);
|
|
||||||
if (res < 0) {
|
|
||||||
goto write_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write Volume Descriptor Set Terminator (ECMA-119, 8.3) */
|
|
||||||
{
|
|
||||||
struct ecma119_vol_desc_terminator *vol;
|
|
||||||
vol = (struct ecma119_vol_desc_terminator *) buf;
|
|
||||||
|
|
||||||
vol->vol_desc_type[0] = 255;
|
|
||||||
memcpy(vol->std_identifier, "CD001", 5);
|
|
||||||
vol->vol_desc_version[0] = 1;
|
|
||||||
|
|
||||||
res = iso_write(target, buf, BLOCK_SIZE);
|
|
||||||
if (res < 0) {
|
|
||||||
goto write_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write superblock checksum tag */
|
|
||||||
if (target->md5_session_checksum && target->checksum_ctx != NULL) {
|
|
||||||
res = iso_md5_write_tag(target, 2);
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto write_error;
|
goto write_error;
|
||||||
}
|
|
||||||
|
|
||||||
/* write data for each writer */
|
/* write data for each writer */
|
||||||
for (i = 0; i < target->nwriters; ++i) {
|
for (i = 0; i < target->nwriters; ++i) {
|
||||||
@ -947,6 +1148,10 @@ void *write_function(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
write_error: ;
|
write_error: ;
|
||||||
|
|
||||||
|
/* TWINTREE: */
|
||||||
|
target->eff_partition_offset = 0;
|
||||||
|
|
||||||
if (res == ISO_CANCELED) {
|
if (res == ISO_CANCELED) {
|
||||||
/* canceled */
|
/* canceled */
|
||||||
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED, 0, NULL);
|
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED, 0, NULL);
|
||||||
@ -1064,15 +1269,20 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
#define Libisofs_twintreE yes
|
||||||
|
|
||||||
static
|
static
|
||||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||||
{
|
{
|
||||||
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
|
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
|
||||||
Ecma119Image *target;
|
Ecma119Image *target;
|
||||||
|
IsoImageWriter *writer;
|
||||||
int el_torito_writer_index = -1, file_src_writer_index = -1;
|
int el_torito_writer_index = -1, file_src_writer_index = -1;
|
||||||
int system_area_options = 0;
|
int system_area_options = 0;
|
||||||
char *system_area = NULL;
|
char *system_area = NULL;
|
||||||
|
int write_count = 0, write_count_mem;
|
||||||
|
|
||||||
/* 1. Allocate target and copy opts there */
|
/* 1. Allocate target and copy opts there */
|
||||||
target = calloc(1, sizeof(Ecma119Image));
|
target = calloc(1, sizeof(Ecma119Image));
|
||||||
@ -1172,6 +1382,18 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->vol_effective_time = opts->vol_effective_time;
|
target->vol_effective_time = opts->vol_effective_time;
|
||||||
strcpy(target->vol_uuid, opts->vol_uuid);
|
strcpy(target->vol_uuid, opts->vol_uuid);
|
||||||
|
|
||||||
|
/* TWINTREE: */
|
||||||
|
target->partition_offset = opts->partition_offset;
|
||||||
|
target->partition_secs_per_head = opts->partition_secs_per_head;
|
||||||
|
target->partition_heads_per_cyl = opts->partition_heads_per_cyl;
|
||||||
|
target->eff_partition_offset = 0;
|
||||||
|
target->partition_root = NULL;
|
||||||
|
target->partition_l_table_pos = 0;
|
||||||
|
target->partition_m_table_pos = 0;
|
||||||
|
target->j_part_root = NULL;
|
||||||
|
target->j_part_l_path_table_pos = 0;
|
||||||
|
target->j_part_m_path_table_pos = 0;
|
||||||
|
|
||||||
target->input_charset = strdup(iso_get_local_charset(0));
|
target->input_charset = strdup(iso_get_local_charset(0));
|
||||||
if (target->input_charset == NULL) {
|
if (target->input_charset == NULL) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
@ -1203,7 +1425,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
target->checksum_array_pos = 0;
|
target->checksum_array_pos = 0;
|
||||||
target->checksum_range_start = 0;
|
target->checksum_range_start = 0;
|
||||||
target->checksum_range_size = 0;
|
target->checksum_range_size = 0;
|
||||||
target->opts_overwrite = 0;
|
target->opts_overwrite = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2. Based on those options, create needed writers: iso, joliet...
|
* 2. Based on those options, create needed writers: iso, joliet...
|
||||||
@ -1215,6 +1437,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
*/
|
*/
|
||||||
target->curblock = target->ms_block + 16;
|
target->curblock = target->ms_block + 16;
|
||||||
|
|
||||||
|
if (opts->overwrite != NULL && target->ms_block != 0 &&
|
||||||
|
target->ms_block < target->partition_offset + 32) {
|
||||||
|
/* TWINTREE: not enough room for superblock relocation */
|
||||||
|
ret = ISO_OVWRT_MS_TOO_SMALL;
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* the number of writers is dependent of the extensions */
|
/* the number of writers is dependent of the extensions */
|
||||||
nwriters = 1 + 1 + 1; /* ECMA-119 + padding + files */
|
nwriters = 1 + 1 + 1; /* ECMA-119 + padding + files */
|
||||||
|
|
||||||
@ -1307,6 +1536,37 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target->partition_offset > 0) {
|
||||||
|
/* >>> TWINTREE: After volume descriptors and superblock tag are
|
||||||
|
accounted for: account for second volset */
|
||||||
|
|
||||||
|
if (target->ms_block + target->partition_offset + 16
|
||||||
|
< target->curblock) {
|
||||||
|
/* TWINTREE: Overflow of partition system area */
|
||||||
|
ret = ISO_PART_OFFST_TOO_SMALL;
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
target->curblock = target->ms_block + target->partition_offset + 16;
|
||||||
|
|
||||||
|
/* TWINTREE: Account for partition tree volume descriptors */
|
||||||
|
for (i = 0; i < target->nwriters; ++i) {
|
||||||
|
/* Not all writers have an entry in the partition
|
||||||
|
volume descriptor set.
|
||||||
|
*/
|
||||||
|
writer = target->writers[i];
|
||||||
|
/* >>> TWINTREE: Enhance ISO1999 writer and add it here */
|
||||||
|
if(writer->write_vol_desc != ecma119_writer_write_vol_desc &&
|
||||||
|
writer->write_vol_desc != joliet_writer_write_vol_desc)
|
||||||
|
continue;
|
||||||
|
target->curblock++;
|
||||||
|
}
|
||||||
|
target->curblock++; /* + Terminator */
|
||||||
|
|
||||||
|
/* >>> TWINTREE: eventually later : second superblock checksum tag */;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 3.
|
* 3.
|
||||||
* Call compute_data_blocks() in each Writer.
|
* Call compute_data_blocks() in each Writer.
|
||||||
@ -1345,13 +1605,54 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
#endif /* Libisofs_patch_ticket_145 */
|
#endif /* Libisofs_patch_ticket_145 */
|
||||||
|
|
||||||
/* create the ring buffer */
|
/* create the ring buffer */
|
||||||
|
if (opts->overwrite != NULL &&
|
||||||
|
opts->fifo_size / 2048 < 32 + target->partition_offset) {
|
||||||
|
/* TWINTREE:
|
||||||
|
The ring buffer must be large enough to take opts->overwrite
|
||||||
|
*/
|
||||||
|
ret = ISO_OVWRT_FIFO_TOO_SMALL;
|
||||||
|
}
|
||||||
ret = iso_ring_buffer_new(opts->fifo_size, &target->buffer);
|
ret = iso_ring_buffer_new(opts->fifo_size, &target->buffer);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we need to provide a copy of volume descriptors */
|
/* check if we need to provide a copy of volume descriptors */
|
||||||
if (opts->overwrite) {
|
if (opts->overwrite != NULL) {
|
||||||
|
|
||||||
|
/* >>> TWINTREE: >>>
|
||||||
|
opts->overwrite must be larger by partion_offset
|
||||||
|
This storage is provided by the application.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_twintreE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In the PVM to be written in the 16th sector of the disc, we
|
||||||
|
* need to specify the full size.
|
||||||
|
*/
|
||||||
|
target->vol_space_size = target->curblock;
|
||||||
|
|
||||||
|
/* System area and volume descriptors */
|
||||||
|
target->opts_overwrite = (char *) opts->overwrite;
|
||||||
|
ret = write_head_part1(target, &write_count, 1 | 2);
|
||||||
|
target->opts_overwrite = NULL;
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
|
||||||
|
/* copy the volume descriptors to the overwrite buffer... */
|
||||||
|
voldesc_size *= BLOCK_SIZE;
|
||||||
|
ret = iso_ring_buffer_read(target->buffer, opts->overwrite,
|
||||||
|
write_count * BLOCK_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_msg_debug(target->image->id,
|
||||||
|
"Error reading overwrite volume descriptors");
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* Libisofs_twintreE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a copy of the volume descriptors to be written in a DVD+RW
|
* Get a copy of the volume descriptors to be written in a DVD+RW
|
||||||
* disc
|
* disc
|
||||||
@ -1378,7 +1679,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the system area */
|
/* write the system area to the start of the overwrite buffer */
|
||||||
ret = iso_write_system_area(target, opts->overwrite);
|
ret = iso_write_system_area(target, opts->overwrite);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_msg_debug(target->image->id,
|
iso_msg_debug(target->image->id,
|
||||||
@ -1386,11 +1687,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip the first 16 blocks (system area) */
|
/* copy the volume descriptors to the overwrite buffer... */
|
||||||
buf = opts->overwrite + 16 * BLOCK_SIZE;
|
buf = opts->overwrite + 16 * BLOCK_SIZE;
|
||||||
voldesc_size *= BLOCK_SIZE;
|
voldesc_size *= BLOCK_SIZE;
|
||||||
|
|
||||||
/* copy the volume descriptors to the overwrite buffer... */
|
|
||||||
ret = iso_ring_buffer_read(target->buffer, buf, voldesc_size);
|
ret = iso_ring_buffer_read(target->buffer, buf, voldesc_size);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_msg_debug(target->image->id,
|
iso_msg_debug(target->image->id,
|
||||||
@ -1405,6 +1704,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
memcpy(vol->std_identifier, "CD001", 5);
|
memcpy(vol->std_identifier, "CD001", 5);
|
||||||
vol->vol_desc_version[0] = 1;
|
vol->vol_desc_version[0] = 1;
|
||||||
|
|
||||||
|
write_count = voldesc_size / BLOCK_SIZE + 16;
|
||||||
|
write_count_mem= write_count;
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_twintreE */
|
||||||
|
|
||||||
/* Write relocated superblock checksum tag */
|
/* Write relocated superblock checksum tag */
|
||||||
tag_pos = voldesc_size / BLOCK_SIZE + 16 + 1;
|
tag_pos = voldesc_size / BLOCK_SIZE + 16 + 1;
|
||||||
if (target->md5_session_checksum) {
|
if (target->md5_session_checksum) {
|
||||||
@ -1422,9 +1726,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
}
|
}
|
||||||
tag_pos++;
|
tag_pos++;
|
||||||
|
write_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean out eventual checksum tags */
|
/* Clean out eventual obsolete checksum tags */
|
||||||
for (i = tag_pos; i < 32; i++) {
|
for (i = tag_pos; i < 32; i++) {
|
||||||
int tag_type;
|
int tag_type;
|
||||||
uint32_t pos, range_start, range_size, next_tag;
|
uint32_t pos, range_start, range_size, next_tag;
|
||||||
@ -1436,6 +1741,22 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
opts->overwrite[i * 2048] = 0;
|
opts->overwrite[i * 2048] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TWINTREE: Write second set of volume descriptors */
|
||||||
|
write_count_mem= write_count;
|
||||||
|
ret = write_head_part2(target, &write_count, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto target_cleanup;
|
||||||
|
|
||||||
|
/* TWINTREE: read written data into opts->overwrite */
|
||||||
|
ret = iso_ring_buffer_read(target->buffer,
|
||||||
|
opts->overwrite + write_count_mem * BLOCK_SIZE,
|
||||||
|
(write_count - write_count_mem) * BLOCK_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_msg_debug(target->image->id,
|
||||||
|
"Error reading overwrite volume descriptors");
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1703,6 +2024,9 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||||||
wopts->vol_expiration_time = 0;
|
wopts->vol_expiration_time = 0;
|
||||||
wopts->vol_effective_time = 0;
|
wopts->vol_effective_time = 0;
|
||||||
wopts->vol_uuid[0] = 0;
|
wopts->vol_uuid[0] = 0;
|
||||||
|
wopts->partition_offset = 0;
|
||||||
|
wopts->partition_secs_per_head = 0;
|
||||||
|
wopts->partition_heads_per_cyl = 0;
|
||||||
|
|
||||||
*opts = wopts;
|
*opts = wopts;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -2130,3 +2454,15 @@ int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||||
|
uint32_t block_offset_2k,
|
||||||
|
int secs_512_per_head, int heads_per_cyl)
|
||||||
|
{
|
||||||
|
if (block_offset_2k > 0 && block_offset_2k < 16)
|
||||||
|
return ISO_PART_OFFST_TOO_SMALL;
|
||||||
|
opts->partition_offset = block_offset_2k;
|
||||||
|
opts->partition_secs_per_head = secs_512_per_head;
|
||||||
|
opts->partition_heads_per_cyl = heads_per_cyl;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -314,6 +314,15 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
char vol_uuid[17];
|
char vol_uuid[17];
|
||||||
|
|
||||||
|
/* TWINTREE: The number of unclaimed 2K blocks before
|
||||||
|
start of partition 1 as of the MBR in system area.
|
||||||
|
Must be 0 or >= 16. (Actually >= #voldescr + checksum tag) */
|
||||||
|
uint32_t partition_offset;
|
||||||
|
/* TWINTREE: Partition table parameter: 1 to 63, 0= disabled/default */
|
||||||
|
int partition_secs_per_head;
|
||||||
|
/* TWINTREE: 1 to 255, 0= disabled/default */
|
||||||
|
int partition_heads_per_cyl;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
@ -404,8 +413,9 @@ struct ecma119_image
|
|||||||
off_t total_size;
|
off_t total_size;
|
||||||
uint32_t vol_space_size;
|
uint32_t vol_space_size;
|
||||||
|
|
||||||
/* Bytes already written, just for progress notification */
|
/* Bytes already written to image output */
|
||||||
off_t bytes_written;
|
off_t bytes_written;
|
||||||
|
/* just for progress notification */
|
||||||
int percent_written;
|
int percent_written;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -531,6 +541,30 @@ struct ecma119_image
|
|||||||
* by unconverted string with timezone 0
|
* by unconverted string with timezone 0
|
||||||
*/
|
*/
|
||||||
char vol_uuid[17];
|
char vol_uuid[17];
|
||||||
|
|
||||||
|
/* TWINTREE: The number of unclaimed 2K blocks before
|
||||||
|
start of partition 1 as of the MBR in system area. */
|
||||||
|
uint32_t partition_offset;
|
||||||
|
/* TWINTREE: Partition table parameter: 1 to 63, 0= disabled/default */
|
||||||
|
int partition_secs_per_head;
|
||||||
|
/* TWINTREE: 1 to 255, 0= disabled/default */
|
||||||
|
int partition_heads_per_cyl;
|
||||||
|
|
||||||
|
/* TWINTREE: The currently applicable LBA offset. To be subtracted from
|
||||||
|
any LBA that is mentioned in volume descriptors or
|
||||||
|
ECMA-119 tree. Either 0 or .partition_offset */
|
||||||
|
uint32_t eff_partition_offset;
|
||||||
|
|
||||||
|
/* TWINTREE: The second ECMA-119 directory tree and path tables */
|
||||||
|
Ecma119Node *partition_root;
|
||||||
|
uint32_t partition_l_table_pos;
|
||||||
|
uint32_t partition_m_table_pos;
|
||||||
|
|
||||||
|
/* TWINTREE: The second Joliet directory tree and path tables */
|
||||||
|
JolietNode *j_part_root;
|
||||||
|
uint32_t j_part_l_path_table_pos;
|
||||||
|
uint32_t j_part_m_path_table_pos;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BP(a,b) [(b) - (a) + 1]
|
#define BP(a,b) [(b) - (a) + 1]
|
||||||
|
@ -714,6 +714,7 @@ static
|
|||||||
int mangle_tree(Ecma119Image *img, int recurse)
|
int mangle_tree(Ecma119Image *img, int recurse)
|
||||||
{
|
{
|
||||||
int max_file, max_dir;
|
int max_file, max_dir;
|
||||||
|
Ecma119Node *root;
|
||||||
|
|
||||||
if (img->max_37_char_filenames) {
|
if (img->max_37_char_filenames) {
|
||||||
max_file = max_dir = 37;
|
max_file = max_dir = 37;
|
||||||
@ -723,10 +724,16 @@ int mangle_tree(Ecma119Image *img, int recurse)
|
|||||||
} else {
|
} else {
|
||||||
max_file = max_dir = 31;
|
max_file = max_dir = 31;
|
||||||
}
|
}
|
||||||
if (recurse) {
|
/* TWINTREE: */
|
||||||
return mangle_dir(img, img->root, max_file, max_dir);
|
if (img->eff_partition_offset > 0) {
|
||||||
|
root = img->partition_root;
|
||||||
} else {
|
} else {
|
||||||
return mangle_single_dir(img, img->root, max_file, max_dir);
|
root = img->root;
|
||||||
|
}
|
||||||
|
if (recurse) {
|
||||||
|
return mangle_dir(img, root, max_file, max_dir);
|
||||||
|
} else {
|
||||||
|
return mangle_single_dir(img, root, max_file, max_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,11 +851,18 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t max_path;
|
size_t max_path;
|
||||||
|
Ecma119Node *root;
|
||||||
|
|
||||||
max_path = pathlen + 1 + max_child_name_len(dir);
|
max_path = pathlen + 1 + max_child_name_len(dir);
|
||||||
|
|
||||||
if (level > 8 || max_path > 255) {
|
if (level > 8 || max_path > 255) {
|
||||||
ret = reparent(dir, img->root);
|
/* TWINTREE: */
|
||||||
|
if (img->eff_partition_offset > 0) {
|
||||||
|
root = img->partition_root;
|
||||||
|
} else {
|
||||||
|
root = img->root;
|
||||||
|
}
|
||||||
|
ret = reparent(dir, root);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1055,10 +1069,16 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
/* TWINTREE: */
|
||||||
|
if (img->eff_partition_offset > 0) {
|
||||||
|
img->partition_root = root;
|
||||||
|
} else {
|
||||||
img->root = root;
|
img->root = root;
|
||||||
|
}
|
||||||
|
|
||||||
iso_msg_debug(img->image->id, "Matching hardlinks...");
|
iso_msg_debug(img->image->id, "Matching hardlinks...");
|
||||||
ret = match_hardlinks(img, img->root, 0);
|
/* TWINTREE: img->root -> root */
|
||||||
|
ret = match_hardlinks(img, root, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1075,7 +1095,8 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||||||
if (img->rockridge && !img->allow_deep_paths) {
|
if (img->rockridge && !img->allow_deep_paths) {
|
||||||
|
|
||||||
/* reorder the tree, acording to RRIP, 4.1.5 */
|
/* reorder the tree, acording to RRIP, 4.1.5 */
|
||||||
ret = reorder_tree(img, img->root, 1, 0);
|
/* TWINTREE: img->root -> root */
|
||||||
|
ret = reorder_tree(img, root, 1, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -942,7 +942,7 @@ int catalog_stream_new(Ecma119Image *target, IsoStream **stream)
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
data = calloc(1, sizeof(struct catalog_stream));
|
data = calloc(1, sizeof(struct catalog_stream));
|
||||||
if (str == NULL) {
|
if (data == NULL) {
|
||||||
free(str);
|
free(str);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
@ -1107,6 +1107,7 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
ret = iso_stream_open(original);
|
ret = iso_stream_open(original);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
free(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = iso_stream_read(original, buf, size);
|
ret = iso_stream_read(original, buf, size);
|
||||||
@ -1157,7 +1158,10 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
memcpy(vol.std_identifier, "CD001", 5);
|
memcpy(vol.std_identifier, "CD001", 5);
|
||||||
vol.vol_desc_version[0] = 1;
|
vol.vol_desc_version[0] = 1;
|
||||||
memcpy(vol.boot_sys_id, "EL TORITO SPECIFICATION", 23);
|
memcpy(vol.boot_sys_id, "EL TORITO SPECIFICATION", 23);
|
||||||
iso_lsb(vol.boot_catalog, t->cat->sections[0].block, 4);
|
|
||||||
|
/* TWINTREE: t->cat->sections[0].block - t->eff_partition_offset */
|
||||||
|
iso_lsb(vol.boot_catalog,
|
||||||
|
t->cat->sections[0].block - t->eff_partition_offset, 4);
|
||||||
|
|
||||||
return iso_write(t, &vol, sizeof(struct ecma119_boot_rec_vol_desc));
|
return iso_write(t, &vol, sizeof(struct ecma119_boot_rec_vol_desc));
|
||||||
}
|
}
|
||||||
|
@ -556,17 +556,20 @@ int joliet_tree_create(Ecma119Image *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* the Joliet tree is stored in Ecma119Image target */
|
/* the Joliet tree is stored in Ecma119Image target */
|
||||||
|
/* TWINTREE: */
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
t->j_part_root = root;
|
||||||
|
} else {
|
||||||
t->joliet_root = root;
|
t->joliet_root = root;
|
||||||
|
}
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Sorting the Joliet tree...");
|
iso_msg_debug(t->image->id, "Sorting the Joliet tree...");
|
||||||
sort_tree(root);
|
sort_tree(root);
|
||||||
|
|
||||||
iso_msg_debug(t->image->id, "Mangling Joliet names...");
|
iso_msg_debug(t->image->id, "Mangling Joliet names...");
|
||||||
ret = mangle_tree(t, t->joliet_root);
|
ret = mangle_tree(t, root);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,6 +676,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
{
|
{
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
uint32_t path_table_size;
|
uint32_t path_table_size;
|
||||||
|
size_t ndirs;
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -696,6 +700,24 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
t->joliet_path_table_size = path_table_size;
|
t->joliet_path_table_size = path_table_size;
|
||||||
|
|
||||||
|
if (t->partition_offset > 0) {
|
||||||
|
/* TWINTREE: take into respect second directory tree */
|
||||||
|
ndirs = t->joliet_ndirs;
|
||||||
|
t->joliet_ndirs = 0;
|
||||||
|
calc_dir_pos(t, t->j_part_root);
|
||||||
|
if (t->joliet_ndirs != ndirs) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||||
|
"Number of directories differs in Joliet partiton_tree");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
/* TWINTREE: take into respect second set of path tables */
|
||||||
|
path_table_size = calc_path_table_size(t->j_part_root);
|
||||||
|
t->j_part_l_path_table_pos = t->curblock;
|
||||||
|
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
|
t->j_part_m_path_table_pos = t->curblock;
|
||||||
|
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,7 +780,8 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
|||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
|
||||||
rec->len_dr[0] = len_dr;
|
rec->len_dr[0] = len_dr;
|
||||||
iso_bb(rec->block, block, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||||
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||||
@ -794,7 +817,6 @@ void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
IsoImage *image;
|
IsoImage *image;
|
||||||
@ -836,15 +858,27 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
/* make use of UCS-2 Level 3 */
|
/* make use of UCS-2 Level 3 */
|
||||||
memcpy(vol.esc_sequences, "%/E", 3);
|
memcpy(vol.esc_sequences, "%/E", 3);
|
||||||
|
|
||||||
iso_bb(vol.vol_space_size, t->vol_space_size, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
|
||||||
|
4);
|
||||||
|
|
||||||
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
|
||||||
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
|
||||||
iso_bb(vol.path_table_size, t->joliet_path_table_size, 4);
|
iso_bb(vol.path_table_size, t->joliet_path_table_size, 4);
|
||||||
|
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
/* TWINTREE: point to second tables and second root */
|
||||||
|
iso_lsb(vol.l_path_table_pos,
|
||||||
|
t->j_part_l_path_table_pos - t->eff_partition_offset, 4);
|
||||||
|
iso_msb(vol.m_path_table_pos,
|
||||||
|
t->j_part_m_path_table_pos - t->eff_partition_offset, 4);
|
||||||
|
write_one_dir_record(t, t->j_part_root, 0, vol.root_dir_record, 1, 0);
|
||||||
|
} else {
|
||||||
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
|
iso_lsb(vol.l_path_table_pos, t->joliet_l_path_table_pos, 4);
|
||||||
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);
|
iso_msb(vol.m_path_table_pos, t->joliet_m_path_table_pos, 4);
|
||||||
|
|
||||||
write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1, 0);
|
write_one_dir_record(t, t->joliet_root, 0, vol.root_dir_record, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ucsncpy_pad((uint16_t*)vol.vol_set_id, volset_id, 128);
|
ucsncpy_pad((uint16_t*)vol.vol_set_id, volset_id, 128);
|
||||||
ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128);
|
ucsncpy_pad((uint16_t*)vol.publisher_id, pub_id, 128);
|
||||||
@ -984,7 +1018,9 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
|||||||
rec = (struct ecma119_path_table_record*) buf;
|
rec = (struct ecma119_path_table_record*) buf;
|
||||||
rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1;
|
rec->len_di[0] = dir->parent ? (uint8_t) ucslen(dir->name) * 2 : 1;
|
||||||
rec->len_xa[0] = 0;
|
rec->len_xa[0] = 0;
|
||||||
write_int(rec->block, dir->info.dir->block, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
write_int(rec->block, dir->info.dir->block - t->eff_partition_offset,
|
||||||
|
4);
|
||||||
write_int(rec->parent, parent + 1, 2);
|
write_int(rec->parent, parent + 1, 2);
|
||||||
if (dir->parent) {
|
if (dir->parent) {
|
||||||
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
|
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
|
||||||
@ -1023,7 +1059,13 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
if (pathlist == NULL) {
|
if (pathlist == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TWINTREE: t->partition_root */
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
pathlist[0] = t->j_part_root;
|
||||||
|
} else {
|
||||||
pathlist[0] = t->joliet_root;
|
pathlist[0] = t->joliet_root;
|
||||||
|
}
|
||||||
cur = 1;
|
cur = 1;
|
||||||
|
|
||||||
for (i = 0; i < t->joliet_ndirs; i++) {
|
for (i = 0; i < t->joliet_ndirs; i++) {
|
||||||
@ -1051,18 +1093,22 @@ int write_path_tables(Ecma119Image *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int joliet_writer_write_data(IsoImageWriter *writer)
|
int joliet_writer_write_dirs(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
|
JolietNode *root;
|
||||||
|
|
||||||
if (writer == NULL) {
|
|
||||||
return ISO_NULL_POINTER;
|
|
||||||
}
|
|
||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
/* first of all, we write the directory structure */
|
/* first of all, we write the directory structure */
|
||||||
ret = write_dirs(t, t->joliet_root);
|
/* TWINTREE: t->root -> root */
|
||||||
|
if (t->eff_partition_offset > 0) {
|
||||||
|
root = t->j_part_root;
|
||||||
|
} else {
|
||||||
|
root = t->joliet_root;
|
||||||
|
}
|
||||||
|
ret = write_dirs(t, root);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1073,12 +1119,41 @@ int joliet_writer_write_data(IsoImageWriter *writer)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int joliet_writer_write_data(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Image *t;
|
||||||
|
|
||||||
|
if (writer == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
t = writer->target;
|
||||||
|
|
||||||
|
ret = joliet_writer_write_dirs(writer);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (t->partition_offset > 0) {
|
||||||
|
/* TWINTREE: */
|
||||||
|
t->eff_partition_offset = t->partition_offset;
|
||||||
|
ret = joliet_writer_write_dirs(writer);
|
||||||
|
t->eff_partition_offset = 0;
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int joliet_writer_free_data(IsoImageWriter *writer)
|
int joliet_writer_free_data(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
/* free the Joliet tree */
|
/* free the Joliet tree */
|
||||||
Ecma119Image *t = writer->target;
|
Ecma119Image *t = writer->target;
|
||||||
joliet_node_free(t->joliet_root);
|
joliet_node_free(t->joliet_root);
|
||||||
|
if (t->j_part_root != NULL)
|
||||||
|
joliet_node_free(t->j_part_root);
|
||||||
|
t->j_part_root = NULL;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,6 +1184,17 @@ int joliet_writer_create(Ecma119Image *target)
|
|||||||
/* add this writer to image */
|
/* add this writer to image */
|
||||||
target->writers[target->nwriters++] = writer;
|
target->writers[target->nwriters++] = writer;
|
||||||
|
|
||||||
|
/* TWINTREE: */
|
||||||
|
if(target->partition_offset > 0) {
|
||||||
|
/* Create second tree */
|
||||||
|
target->eff_partition_offset = target->partition_offset;
|
||||||
|
ret = joliet_tree_create(target);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
target->eff_partition_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* we need the volume descriptor */
|
/* we need the volume descriptor */
|
||||||
target->curblock++;
|
target->curblock++;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
@ -54,4 +54,10 @@ struct joliet_node
|
|||||||
*/
|
*/
|
||||||
int joliet_writer_create(Ecma119Image *target);
|
int joliet_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
|
|
||||||
|
/* TWINTREE: Not to be called but only for comparison with target->writers[i]
|
||||||
|
*/
|
||||||
|
int joliet_writer_write_vol_desc(IsoImageWriter *writer);
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIBISO_JOLIET_H */
|
#endif /* LIBISO_JOLIET_H */
|
||||||
|
@ -1693,9 +1693,12 @@ int iso_write_opts_set_ms_block(IsoWriteOpts *opts, uint32_t ms_block);
|
|||||||
* - Together with iso_write_opts_set_appendable(opts, 0) the buffer allows
|
* - Together with iso_write_opts_set_appendable(opts, 0) the buffer allows
|
||||||
* to write the first session on overwriteable media to start addresses
|
* to write the first session on overwriteable media to start addresses
|
||||||
* other than 0.
|
* other than 0.
|
||||||
|
* This address must not be smaller than 32 blocks plus the eventual
|
||||||
|
* partition offset as defined by iso_write_opts_set_part_offset().
|
||||||
* libisoburn in most cases writes the first session on overwriteable media
|
* libisoburn in most cases writes the first session on overwriteable media
|
||||||
* and disk files to LBA 32 in order to preserve its descriptors from the
|
* and disk files to LBA (32 + partition_offset) in order to preserve its
|
||||||
* subsequent overwriting by the descriptor buffer of later sessions.
|
* descriptors from the subsequent overwriting by the descriptor buffer of
|
||||||
|
* later sessions.
|
||||||
*
|
*
|
||||||
* @param opts
|
* @param opts
|
||||||
* The option set to be manipulated.
|
* The option set to be manipulated.
|
||||||
@ -1713,7 +1716,7 @@ int iso_write_opts_set_ms_block(IsoWriteOpts *opts, uint32_t ms_block);
|
|||||||
int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite);
|
int iso_write_opts_set_overwrite_buf(IsoWriteOpts *opts, uint8_t *overwrite);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the size, in number of blocks, of the FIFO buffer used between the
|
* Set the size, in number of blocks, of the ring buffer used between the
|
||||||
* writer thread and the burn_source. You have to provide at least a 32
|
* writer thread and the burn_source. You have to provide at least a 32
|
||||||
* blocks buffer. Default value is set to 2MB, if that is ok for you, you
|
* blocks buffer. Default value is set to 2MB, if that is ok for you, you
|
||||||
* don't need to call this function.
|
* don't need to call this function.
|
||||||
@ -1761,6 +1764,8 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
|||||||
* Explicitely set the four timestamps of the emerging Primary Volume
|
* Explicitely set the four timestamps of the emerging Primary Volume
|
||||||
* Descriptor. Default with all parameters is 0.
|
* Descriptor. Default with all parameters is 0.
|
||||||
* ECMA-119 defines them as:
|
* ECMA-119 defines them as:
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
* @param vol_creation_time
|
* @param vol_creation_time
|
||||||
* When "the information in the volume was created."
|
* When "the information in the volume was created."
|
||||||
* A value of 0 means that the timepoint of write start is to be used.
|
* A value of 0 means that the timepoint of write start is to be used.
|
||||||
@ -1782,6 +1787,8 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
|
|||||||
* is fully predictable and free of timezone pitfalls.
|
* is fully predictable and free of timezone pitfalls.
|
||||||
* It should express a reasonable time in form YYYYMMDDhhmmsscc
|
* It should express a reasonable time in form YYYYMMDDhhmmsscc
|
||||||
* E.g.: "2010040711405800" = 7 Apr 2010 11:40:58 (+0 centiseconds)
|
* E.g.: "2010040711405800" = 7 Apr 2010 11:40:58 (+0 centiseconds)
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
*
|
*
|
||||||
* @since 0.6.30
|
* @since 0.6.30
|
||||||
*/
|
*/
|
||||||
@ -1791,6 +1798,44 @@ int iso_write_opts_set_pvd_times(IsoWriteOpts *opts,
|
|||||||
char *vol_uuid);
|
char *vol_uuid);
|
||||||
|
|
||||||
|
|
||||||
|
/* CAUTION : Not yet completely implemented for checksums in the second tree
|
||||||
|
* set and not yet tested for multi-session with overwrite buffer.
|
||||||
|
* Already usable for single session including bootability and
|
||||||
|
* Joliet directory tree.
|
||||||
|
*
|
||||||
|
* Control production of a second set of volume descriptors (superblock)
|
||||||
|
* and directory trees, together with a partition table entry in the MBR which
|
||||||
|
* has non-zero start address.
|
||||||
|
* The second volume descriptor set and trees will allow to mount the ISO image
|
||||||
|
* at the start of the first partition, while it is still possible to mount it
|
||||||
|
* via the normal first volume descriptor set and tree at the start of the
|
||||||
|
* image resp. storage device.
|
||||||
|
* This makes few sense on optical media. But on USB sticks it creates a
|
||||||
|
* conventional partition table which makes it mountable on e.g. Linux via
|
||||||
|
* /dev/sdb and /dev/sdb1 alike.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param block_offset_2k
|
||||||
|
* The offset of the partition start relative to device start.
|
||||||
|
* This is counted in 2 kB blocks. The partition table will show the
|
||||||
|
* according number of 512 byte sectors.
|
||||||
|
* Default is 0 which causes no second set and trees.
|
||||||
|
* If it is not 0 then it must not be smaller than 16.
|
||||||
|
* @param secs_512_per_head
|
||||||
|
* Number of 512 byte sectors per head. 1 to 63. 0=automatic.
|
||||||
|
* @param heads_per_cyl
|
||||||
|
* Number of heads per cylinder. 1 to 255. 0=automatic.
|
||||||
|
* @return
|
||||||
|
* ISO_SUCCESS or error
|
||||||
|
*
|
||||||
|
* @since 0.6.36
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||||
|
uint32_t block_offset_2k,
|
||||||
|
int secs_512_per_head, int heads_per_cyl);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire the start address of the file data blocks after having used
|
* Inquire the start address of the file data blocks after having used
|
||||||
* IsoWriteOpts with iso_image_create_burn_source().
|
* IsoWriteOpts with iso_image_create_burn_source().
|
||||||
@ -6071,8 +6116,35 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
*/
|
*/
|
||||||
#define ISO_SCDBACKUP_TAG_NOT_0 0xD030FE99
|
#define ISO_SCDBACKUP_TAG_NOT_0 0xD030FE99
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The setting of iso_write_opts_set_ms_block() leaves not enough room
|
||||||
|
* for the prescibed size of iso_write_opts_set_overwrite_buf().
|
||||||
|
* (FAILURE, HIGH, -360)
|
||||||
|
* @since 0.6.36
|
||||||
|
*/
|
||||||
|
#define ISO_OVWRT_MS_TOO_SMALL 0xE830FE98
|
||||||
|
|
||||||
/* ! PLACE NEW ERROR CODES HERE ! */
|
/**
|
||||||
|
* The partition offset is not 0 and leaves not not enough room for
|
||||||
|
* system area, volume descriptors, and checksum tags of the first tree.
|
||||||
|
* (FAILURE, HIGH, -361)
|
||||||
|
*/
|
||||||
|
#define ISO_PART_OFFST_TOO_SMALL 0xE830FE97
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ring buffer is smaller than 64 kB + partition offset.
|
||||||
|
* (FAILURE, HIGH, -362)
|
||||||
|
*/
|
||||||
|
#define ISO_OVWRT_FIFO_TOO_SMALL 0xE830FE96
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal developer note:
|
||||||
|
Place new error codes directly above this comment.
|
||||||
|
Newly introduced errors must get a message entry in
|
||||||
|
libisofs/message.c, function iso_error_to_msg()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */
|
||||||
|
|
||||||
|
|
||||||
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
|
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
|
||||||
@ -6088,7 +6160,7 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
|
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
|
||||||
|
|
||||||
|
|
||||||
/* ! PLACE NEW ERROR CODES ABOVE. NOT HERE ! */
|
/* ! PLACE NEW ERROR CODES SEVERAL LINES ABOVE. NOT HERE ! */
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
@ -272,6 +272,7 @@ iso_write_opts_set_no_force_dots;
|
|||||||
iso_write_opts_set_omit_version_numbers;
|
iso_write_opts_set_omit_version_numbers;
|
||||||
iso_write_opts_set_output_charset;
|
iso_write_opts_set_output_charset;
|
||||||
iso_write_opts_set_overwrite_buf;
|
iso_write_opts_set_overwrite_buf;
|
||||||
|
iso_write_opts_set_part_offset;
|
||||||
iso_write_opts_set_pvd_times;
|
iso_write_opts_set_pvd_times;
|
||||||
iso_write_opts_set_record_md5;
|
iso_write_opts_set_record_md5;
|
||||||
iso_write_opts_set_relaxed_vol_atts;
|
iso_write_opts_set_relaxed_vol_atts;
|
||||||
|
@ -286,6 +286,12 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Session does not start at LBA 0. scdbackup checksum tag not written.";
|
return "Session does not start at LBA 0. scdbackup checksum tag not written.";
|
||||||
case ISO_BOOT_NO_CATALOG:
|
case ISO_BOOT_NO_CATALOG:
|
||||||
return "No boot catalog created yet";
|
return "No boot catalog created yet";
|
||||||
|
case ISO_OVWRT_MS_TOO_SMALL:
|
||||||
|
return "Multi-session offset too small for overwrite buffer";
|
||||||
|
case ISO_PART_OFFST_TOO_SMALL:
|
||||||
|
return "Partition offset too small for first tree root.";
|
||||||
|
case ISO_OVWRT_FIFO_TOO_SMALL:
|
||||||
|
return "The ring buffer is too small for overwrite buffer";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -184,7 +184,9 @@ int rrip_add_PL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
|||||||
PL[3] = 1;
|
PL[3] = 1;
|
||||||
|
|
||||||
/* write the location of the real parent, already computed */
|
/* write the location of the real parent, already computed */
|
||||||
iso_bb(&PL[4], n->info.dir->real_parent->info.dir->block, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
iso_bb(&PL[4],
|
||||||
|
n->info.dir->real_parent->info.dir->block - t->eff_partition_offset, 4);
|
||||||
return susp_append(t, susp, PL);
|
return susp_append(t, susp, PL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +279,9 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
|||||||
CL[1] = 'L';
|
CL[1] = 'L';
|
||||||
CL[2] = 12;
|
CL[2] = 12;
|
||||||
CL[3] = 1;
|
CL[3] = 1;
|
||||||
iso_bb(&CL[4], n->info.real_me->info.dir->block, 4);
|
/* TWINTREE: - t->eff_partition_offset */
|
||||||
|
iso_bb(&CL[4], n->info.real_me->info.dir->block - t->eff_partition_offset,
|
||||||
|
4);
|
||||||
return susp_append(t, susp, CL);
|
return susp_append(t, susp, CL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,7 +701,9 @@ int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
|
|||||||
CE[1] = 'E';
|
CE[1] = 'E';
|
||||||
CE[2] = 28;
|
CE[2] = 28;
|
||||||
CE[3] = 1;
|
CE[3] = 1;
|
||||||
iso_bb(&CE[4], susp->ce_block, 4);
|
|
||||||
|
/* TWINTREE: susp->ce_block - t->eff_partition_offset */
|
||||||
|
iso_bb(&CE[4], susp->ce_block - t->eff_partition_offset, 4);
|
||||||
iso_bb(&CE[12], susp->ce_len, 4);
|
iso_bb(&CE[12], susp->ce_len, 4);
|
||||||
iso_bb(&CE[20], (uint32_t) ce_len, 4);
|
iso_bb(&CE[20], (uint32_t) ce_len, 4);
|
||||||
|
|
||||||
|
@ -32,12 +32,42 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
|
|||||||
* Be cautious with changing parameters. Only few combinations are tested.
|
* Be cautious with changing parameters. Only few combinations are tested.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
int make_isolinux_mbr(uint32_t *img_blocks, uint32_t boot_lba,
|
||||||
uint32_t mbr_id, int head_count, int sector_count,
|
uint32_t mbr_id, int head_count, int sector_count,
|
||||||
int part_offset, int part_number, int fs_type,
|
int part_offset, int part_number, int fs_type,
|
||||||
uint8_t *buf, int flag);
|
uint8_t *buf, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param flag bit0= img_blocks is start address rather than end address:
|
||||||
|
do not subtract 1
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void iso_compute_cyl_head_sec(uint32_t *img_blocks, int hpc, int sph,
|
||||||
|
uint32_t *end_lba, uint32_t *end_sec,
|
||||||
|
uint32_t *end_head, uint32_t *end_cyl, int flag)
|
||||||
|
{
|
||||||
|
uint32_t secs;
|
||||||
|
|
||||||
|
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
||||||
|
if (*img_blocks >= 0x40000000)
|
||||||
|
*img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
||||||
|
if (flag & 1)
|
||||||
|
secs = *end_lba = *img_blocks * 4; /* first valid 512-lba */
|
||||||
|
else
|
||||||
|
secs = *end_lba = *img_blocks * 4 - 1; /* last valid 512-lba */
|
||||||
|
*end_cyl = secs / (sph * hpc);
|
||||||
|
secs -= *end_cyl * sph * hpc;
|
||||||
|
*end_head = secs / sph;
|
||||||
|
*end_sec = secs - *end_head * sph + 1; /* Sector count starts by 1 */
|
||||||
|
if (*end_cyl >= 1024) {
|
||||||
|
*end_cyl = 1023;
|
||||||
|
*end_head = hpc - 1;
|
||||||
|
*end_sec = sph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
/* This is the gesture of grub-mkisofs --protective-msdos-label as explained by
|
||||||
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
Vladimir Serbinenko <phcoder@gmail.com>, 2 April 2010, on grub-devel@gnu.org
|
||||||
"Currently we use first and not last entry. You need to:
|
"Currently we use first and not last entry. You need to:
|
||||||
@ -53,38 +83,35 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
|||||||
should go into bytes 458-461. But with a start lba of 1, this is the
|
should go into bytes 458-461. But with a start lba of 1, this is the
|
||||||
same number.
|
same number.
|
||||||
See also http://en.wikipedia.org/wiki/Master_boot_record
|
See also http://en.wikipedia.org/wiki/Master_boot_record
|
||||||
|
|
||||||
|
flag bit0= do not write 0x55, 0xAA to 510,511
|
||||||
|
bit1= do not mark partition as bootable
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int make_grub_msdos_label(int img_blocks, uint8_t *buf, int flag)
|
int make_grub_msdos_label(uint32_t img_blocks, uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
uint8_t *wpt;
|
uint8_t *wpt;
|
||||||
unsigned long end_lba, secs, end_sec, end_head, end_cyl;
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
int sph = 63, hpc = 255, i;
|
int sph = 63, hpc = 255, i;
|
||||||
|
|
||||||
/* Partition table unit is 512 bytes per sector, ECMA-119 unit is 2048 */
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||||
if (img_blocks >= 0x40000000)
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
img_blocks = 0x40000000 - 1; /* truncate rather than roll over */
|
|
||||||
secs = end_lba = img_blocks * 4 - 1; /* last valid 512-lba */
|
|
||||||
end_cyl = secs / (sph * hpc);
|
|
||||||
secs -= end_cyl * sph * hpc;
|
|
||||||
end_head = secs / sph;
|
|
||||||
end_sec = secs - end_head * sph + 1; /* Sector count starts by 1 */
|
|
||||||
if (end_cyl >= 1024) {
|
|
||||||
end_cyl = 1023;
|
|
||||||
end_head = hpc - 1;
|
|
||||||
end_sec = sph;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 1) Zero-fill 446-510 */
|
/* 1) Zero-fill 446-510 */
|
||||||
wpt = buf + 446;
|
wpt = buf + 446;
|
||||||
memset(wpt, 0, 64);
|
memset(wpt, 0, 64);
|
||||||
|
|
||||||
|
if (!(flag & 1)) {
|
||||||
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
|
/* 2) Put 0x55, 0xAA into 510-512 (actually 510-511) */
|
||||||
buf[510] = 0x55;
|
buf[510] = 0x55;
|
||||||
buf[511] = 0xAA;
|
buf[511] = 0xAA;
|
||||||
|
}
|
||||||
|
if (!(flag & 2)) {
|
||||||
/* 3) Put 0x80 (for bootable partition), */
|
/* 3) Put 0x80 (for bootable partition), */
|
||||||
*(wpt++) = 0x80;
|
*(wpt++) = 0x80;
|
||||||
|
} else {
|
||||||
|
*(wpt++) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* 0, 2, 0 (C/H/S of the start), */
|
/* 0, 2, 0 (C/H/S of the start), */
|
||||||
*(wpt++) = 0;
|
*(wpt++) = 0;
|
||||||
@ -120,10 +147,63 @@ int make_grub_msdos_label(int img_blocks, uint8_t *buf, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_offset_partition_start(uint32_t img_blocks, uint32_t partition_offset,
|
||||||
|
int sph_in, int hpc_in, uint8_t *buf, int flag)
|
||||||
|
{
|
||||||
|
uint8_t *wpt;
|
||||||
|
uint32_t end_lba, end_sec, end_head, end_cyl;
|
||||||
|
uint32_t start_lba, start_sec, start_head, start_cyl;
|
||||||
|
int sph = 63, hpc = 255, i;
|
||||||
|
|
||||||
|
if (sph_in > 0)
|
||||||
|
sph = sph_in;
|
||||||
|
if (hpc_in > 0)
|
||||||
|
hpc = hpc_in;
|
||||||
|
iso_compute_cyl_head_sec(&partition_offset, hpc, sph,
|
||||||
|
&start_lba, &start_sec, &start_head, &start_cyl, 1);
|
||||||
|
iso_compute_cyl_head_sec(&img_blocks, hpc, sph,
|
||||||
|
&end_lba, &end_sec, &end_head, &end_cyl, 0);
|
||||||
|
wpt = buf + 446;
|
||||||
|
|
||||||
|
wpt++;
|
||||||
|
|
||||||
|
/* C/H/S of the start */
|
||||||
|
*(wpt++) = start_head;
|
||||||
|
*(wpt++) = start_sec | ((start_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
/* (partition type) */
|
||||||
|
wpt++;
|
||||||
|
|
||||||
|
/* 3 bytes of C/H/S end */
|
||||||
|
*(wpt++) = end_head;
|
||||||
|
*(wpt++) = end_sec | ((end_cyl & 0x300) >> 2);
|
||||||
|
*(wpt++) = end_cyl & 0xff;
|
||||||
|
|
||||||
|
/* LBA start in little endian */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (start_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* Number of sectors in partition, little endian */
|
||||||
|
end_lba = end_lba - start_lba + 1;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
*(wpt++) = (end_lba >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
|
/* at 446-462 */
|
||||||
|
if (wpt - buf != 462) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs: program error in iso_offset_partition_start: \"assert 462\"\n");
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, int_img_blocks;
|
||||||
int img_blocks;
|
uint32_t img_blocks;
|
||||||
|
|
||||||
if ((t == NULL) || (buf == NULL)) {
|
if ((t == NULL) || (buf == NULL)) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -142,8 +222,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
/* Check for isolinux image with magic number of 3.72 and produce
|
/* Check for isolinux image with magic number of 3.72 and produce
|
||||||
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||||
*/
|
*/
|
||||||
|
if (img_blocks < 0x80000000) {
|
||||||
|
int_img_blocks= img_blocks;
|
||||||
|
} else {
|
||||||
|
int_img_blocks= 0x7ffffff0;
|
||||||
|
}
|
||||||
ret = make_isohybrid_mbr(t->bootsrc[0]->sections[0].block,
|
ret = make_isohybrid_mbr(t->bootsrc[0]->sections[0].block,
|
||||||
&img_blocks, (char*)buf, 0);
|
&int_img_blocks, (char*)buf, 0);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
/* error, it should never happen */
|
/* error, it should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
@ -151,9 +236,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
if (t->system_area_options & 1) {
|
if (t->system_area_options & 1) {
|
||||||
/* Write GRUB protective msdos label, i.e. a isimple partition table */
|
/* Write GRUB protective msdos label, i.e. a simple partition table */
|
||||||
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
ret = make_grub_msdos_label(img_blocks, buf, 0);
|
||||||
if (ret != 1) /* error should never happen */
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
} else if(t->system_area_options & 2) {
|
} else if(t->system_area_options & 2) {
|
||||||
/* Patch externally provided system area as isohybrid MBR */
|
/* Patch externally provided system area as isohybrid MBR */
|
||||||
@ -167,6 +252,23 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
|||||||
(uint32_t) 0, 64, 32, 0, 1, 0x17, buf, 1);
|
(uint32_t) 0, 64, 32, 0, 1, 0x17, buf, 1);
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if(t->partition_offset > 0) {
|
||||||
|
/* Write a simple partition table. */
|
||||||
|
/* >>> TWINTREE: ??? Shall the partition stay marked as bootable ? */
|
||||||
|
ret = make_grub_msdos_label(img_blocks, buf, 2);
|
||||||
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t->partition_offset > 0) {
|
||||||
|
/* TWINTREE: adjust partition table to partition offset */
|
||||||
|
img_blocks = t->curblock; /* value might be altered */
|
||||||
|
ret = iso_offset_partition_start(img_blocks, t->partition_offset,
|
||||||
|
t->partition_secs_per_head,
|
||||||
|
t->partition_heads_per_cyl, buf, 0);
|
||||||
|
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||||
|
return ISO_ASSERT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user