Support for writting ISO Level 3 images.
This allows files greater than 4GB, that are written using multiple extents.
This commit is contained in:
parent
68bd636bd8
commit
6ff7699c47
@ -235,11 +235,13 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||||
uint8_t *buf, size_t len_fi, struct susp_info *info)
|
uint8_t *buf, size_t len_fi, struct susp_info *info,
|
||||||
|
int extent)
|
||||||
{
|
{
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t block;
|
uint32_t block;
|
||||||
uint8_t len_dr; /*< size of dir entry without SUSP fields */
|
uint8_t len_dr; /*< size of dir entry without SUSP fields */
|
||||||
|
int multi_extend = 0;
|
||||||
uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id
|
uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id
|
||||||
: (uint8_t*)node->iso_name;
|
: (uint8_t*)node->iso_name;
|
||||||
|
|
||||||
@ -260,8 +262,17 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
|||||||
len = node->info.dir->len;
|
len = node->info.dir->len;
|
||||||
block = node->info.dir->block;
|
block = node->info.dir->block;
|
||||||
} else if (node->type == ECMA119_FILE) {
|
} else if (node->type == ECMA119_FILE) {
|
||||||
len = iso_file_src_get_size(node->info.file);
|
off_t size = iso_file_src_get_size(node->info.file)
|
||||||
|
- ((off_t)0xFFFFF800) * (off_t)extent; /* bytes in another extent */
|
||||||
|
if (size > (off_t) 0xffffffff) {
|
||||||
|
/* 2097151 is the number of blocks needed to store 4 GB - 2048 */
|
||||||
|
block = node->info.file->block + extent * 2097151;
|
||||||
|
len = 0xFFFFF800;
|
||||||
|
multi_extend = 1;
|
||||||
|
} else {
|
||||||
|
len = (uint32_t) size;
|
||||||
block = node->info.file->block;
|
block = node->info.file->block;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* for nodes other than files and dirs, we set both
|
* for nodes other than files and dirs, we set both
|
||||||
@ -281,7 +292,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
|||||||
iso_bb(rec->block, block, 4);
|
iso_bb(rec->block, block, 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 == ECMA119_DIR) ? 2 : 0;
|
rec->flags[0] = ((node->type == ECMA119_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||||
iso_bb(rec->vol_seq_number, 1, 2);
|
iso_bb(rec->vol_seq_number, 1, 2);
|
||||||
rec->len_fi[0] = len_fi;
|
rec->len_fi[0] = len_fi;
|
||||||
|
|
||||||
@ -365,7 +376,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
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);
|
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);
|
||||||
@ -429,7 +440,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = 34 + info.suf_len;
|
len = 34 + info.suf_len;
|
||||||
write_one_dir_record(t, dir, 0, buf, 1, &info);
|
write_one_dir_record(t, dir, 0, buf, 1, &info, 0);
|
||||||
buf += len;
|
buf += len;
|
||||||
|
|
||||||
if (t->rockridge) {
|
if (t->rockridge) {
|
||||||
@ -439,12 +450,15 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = 34 + info.suf_len;
|
len = 34 + info.suf_len;
|
||||||
write_one_dir_record(t, dir, 1, buf, 1, &info);
|
write_one_dir_record(t, dir, 1, buf, 1, &info, 0);
|
||||||
buf += len;
|
buf += len;
|
||||||
|
|
||||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||||
Ecma119Node *child = dir->info.dir->children[i];
|
Ecma119Node *child = dir->info.dir->children[i];
|
||||||
|
|
||||||
|
int extent = 0;
|
||||||
|
do {
|
||||||
|
|
||||||
/* compute len of directory entry */
|
/* compute len of directory entry */
|
||||||
fi_len = strlen(child->iso_name);
|
fi_len = strlen(child->iso_name);
|
||||||
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
|
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
|
||||||
@ -471,8 +485,22 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
buf = buffer;
|
buf = buffer;
|
||||||
}
|
}
|
||||||
/* write the directory entry in any case */
|
/* write the directory entry in any case */
|
||||||
write_one_dir_record(t, child, -1, buf, fi_len, &info);
|
write_one_dir_record(t, child, -1, buf, fi_len, &info, extent);
|
||||||
buf += len;
|
buf += len;
|
||||||
|
|
||||||
|
if (child->type == ECMA119_FILE) {
|
||||||
|
/* check if file is too big and need more extents */
|
||||||
|
off_t size = iso_file_src_get_size(child->info.file)
|
||||||
|
- ((off_t)0xFFFFF800) * (off_t)extent;
|
||||||
|
if (size > (off_t) 0xffffffff) {
|
||||||
|
extent++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break; /* we only have a single extent */
|
||||||
|
}
|
||||||
|
} while(1); /* loop for each extend */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the last block */
|
/* write the last block */
|
||||||
@ -1315,7 +1343,7 @@ int iso_write_opts_set_iso_level(IsoWriteOpts *opts, int level)
|
|||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (level != 1 && level != 2) {
|
if (level != 1 && level != 2 && level != 3) {
|
||||||
return ISO_WRONG_ARG_VALUE;
|
return ISO_WRONG_ARG_VALUE;
|
||||||
}
|
}
|
||||||
opts->level = level;
|
opts->level = level;
|
||||||
|
@ -161,7 +161,7 @@ int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
|
|||||||
off_t size;
|
off_t size;
|
||||||
|
|
||||||
size = iso_stream_get_size(iso->stream);
|
size = iso_stream_get_size(iso->stream);
|
||||||
if (size > (off_t)0xffffffff) {
|
if (size > (off_t)0xffffffff && img->iso_level != 3) {
|
||||||
return iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
|
return iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
|
||||||
"File \"%s\" can't be added to image because "
|
"File \"%s\" can't be added to image because "
|
||||||
"is greater than 4GB", iso->node.name);
|
"is greater than 4GB", iso->node.name);
|
||||||
|
@ -259,11 +259,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
|||||||
i = 0;
|
i = 0;
|
||||||
while ((file = filelist[i++]) != NULL) {
|
while ((file = filelist[i++]) != NULL) {
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO WARNING
|
|
||||||
* when we allow files greater than 4GB, current DIV_UP implementation
|
|
||||||
* can overflow!!
|
|
||||||
*/
|
|
||||||
uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||||
|
|
||||||
res = filesrc_open(file);
|
res = filesrc_open(file);
|
||||||
|
@ -937,6 +937,7 @@ void iso_write_opts_free(IsoWriteOpts *opts);
|
|||||||
* -> 1 for higher compatibility with old systems. With this level
|
* -> 1 for higher compatibility with old systems. With this level
|
||||||
* filenames are restricted to 8.3 characters.
|
* filenames are restricted to 8.3 characters.
|
||||||
* -> 2 to allow up to 31 filename characters.
|
* -> 2 to allow up to 31 filename characters.
|
||||||
|
* -> 3 to allow files greater than 4GB
|
||||||
* @return
|
* @return
|
||||||
* 1 success, < 0 error
|
* 1 success, < 0 error
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user