RockRidge support, now RR/SUSP entries are correctly written.

This also fix a little bug, ensuring SP is written first to the "." 
entry of the directory record.
This commit is contained in:
Vreixo Formoso 2007-12-25 18:35:10 +01:00
parent 54038ec54b
commit f8f2dcb6b0
3 changed files with 88 additions and 14 deletions

View File

@ -368,7 +368,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
memset(&info, 0, sizeof(struct susp_info));
if (t->rockridge) {
/* initialize the ce_block, it might be needed */
info.ce_block = div_up(dir->info.dir.block + dir->info.dir.len,
info.ce_block = dir->info.dir.block + div_up(dir->info.dir.len,
BLOCK_SIZE);
}
@ -379,8 +379,9 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
return ret;
}
}
len = 34 + info.suf_len;
write_one_dir_record(t, dir, 0, buf, 1, &info);
buf += 34 + info.suf_len;
buf += len;
if (t->rockridge) {
ret = rrip_get_susp_fields(t, dir, 2, 255 - 32, &info);
@ -388,8 +389,9 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
return ret;
}
}
len = 34 + info.suf_len;
write_one_dir_record(t, dir, 1, buf, 1, &info);
buf += 34 + info.suf_len;
buf += len;
for (i = 0; i < dir->info.dir.nchildren; i++) {
Ecma119Node *child = dir->info.dir.children[i];

View File

@ -11,6 +11,7 @@
#include "node.h"
#include "ecma119_tree.h"
#include "error.h"
#include "writer.h"
#include <string.h>
@ -717,6 +718,16 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
*/
space--;
/*
* SP must be the first entry for the "." record of the root directory
*/
if (type == 1 && n->parent == NULL) {
ret = susp_add_SP(t, info);
if (ret < 0) {
goto add_susp_cleanup;
}
}
/* PX and TF, we are sure they always fit in SUA */
ret = rrip_add_PX(t, node, info);
if (ret < 0) {
@ -1009,12 +1020,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/*
* "." for root directory
* we need to write SP and ER entries. The first fits in SUA,
* ER needs a Continuation Area, thus we also need a CE entry
* ER needs a Continuation Area, thus we also need a CE entry.
* Note that SP entry was already added above
*/
ret = susp_add_SP(t, info);
if (ret < 0) {
goto add_susp_cleanup;
}
ret = susp_add_CE(t, 182, info); /* 182 is ER length */
if (ret < 0) {
goto add_susp_cleanup;
@ -1026,6 +1034,12 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
}
/*
* The System Use field inside the directory record must be padded if
* it is an odd number (ECMA-119, 9.1.13)
*/
info->suf_len += (info->suf_len % 2);
return ISO_SUCCESS;
add_susp_cleanup:;
@ -1033,15 +1047,73 @@ add_susp_cleanup:;
return ret;
}
/**
* Write the given SUSP fields into buf. Note that Continuation Area
* fields are not written.
* If info does not contain any SUSP entry this function just return.
* After written, the info susp_fields array will be freed, and the counters
* updated propertly.
*/
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
void *buf)
uint8_t *buf)
{
//TODO to implement
size_t i;
size_t pos = 0;
for (i = 0; i < info->n_susp_fields; i++) {
memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]);
pos += info->susp_fields[i][2];
}
/* free susp_fields */
for (i = 0; i < info->n_susp_fields; ++i) {
free(info->susp_fields[i]);
}
free(info->susp_fields);
info->susp_fields = NULL;
info->n_susp_fields = 0;
info->suf_len = 0;
}
/**
* Write the Continuation Area entries for the given struct susp_info, using
* the iso_write() function.
* After written, the ce_susp_fields array will be freed.
*/
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
{
//TODO to implement
return -1;
size_t i;
uint8_t padding[BLOCK_SIZE];
int ret = ISO_SUCCESS;
if (info->n_ce_susp_fields == 0) {
return ret;
}
for (i = 0; i < info->n_ce_susp_fields; i++) {
ret = iso_write(t, info->ce_susp_fields[i],
info->ce_susp_fields[i][2]);
if (ret < 0) {
goto write_ce_field_cleanup;
}
}
/* pad continuation area until block size */
i = BLOCK_SIZE - (info->ce_len % BLOCK_SIZE);
if (i > 0 && i < BLOCK_SIZE) {
memset(padding, 0, i);
ret = iso_write(t, padding, i);
}
write_ce_field_cleanup:;
/* free ce_susp_fields */
for (i = 0; i < info->n_ce_susp_fields; ++i) {
free(info->ce_susp_fields[i]);
}
free(info->ce_susp_fields);
info->ce_susp_fields = NULL;
info->n_ce_susp_fields = 0;
info->ce_len = 0;
return ret;
}

View File

@ -97,7 +97,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* updated propertly.
*/
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
void *buf);
uint8_t *buf);
/**
* Write the Continuation Area entries for the given struct susp_info, using