UDF file reading works for strategy 4. What a pain in the ass.
This commit is contained in:
@@ -618,12 +618,16 @@ typedef struct udf_icbtag_s udf_icbtag_t;
|
|||||||
#define UDF_ICB_TAG_FLAGS_SETGID 0x80
|
#define UDF_ICB_TAG_FLAGS_SETGID 0x80
|
||||||
#define UDF_ICB_TAG_FLAGS_STICKY 0x100
|
#define UDF_ICB_TAG_FLAGS_STICKY 0x100
|
||||||
|
|
||||||
/** Strategy Type (ECMA 167r3 4/14.6.2) */
|
/** Strategy Type (ECMA 167r3 4/14.6.2) which helpfully points
|
||||||
|
largely to 4/A.x */
|
||||||
#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
|
#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
|
||||||
#define ICBTAG_STRATEGY_TYPE_1 0x0001
|
#define ICBTAG_STRATEGY_TYPE_1 0x0001 /**< 4/A.2 Direct entries Uint16 */
|
||||||
#define ICBTAG_STRATEGY_TYPE_2 0x0002
|
#define ICBTAG_STRATEGY_TYPE_2 0x0002 /**< 4/A.3 List of ICB direct entries */
|
||||||
#define ICBTAG_STRATEGY_TYPE_3 0x0003
|
#define ICBTAG_STRATEGY_TYPE_3 0x0003 /**< 4/A.4 */
|
||||||
#define ICBTAG_STRATEGY_TYPE_4 0x0004
|
#define ICBTAG_STRATEGY_TYPE_4 0x0004 /**< 4/A.5 Hierarchy having one
|
||||||
|
single ICB with one direct entry.
|
||||||
|
This is what's most often used.
|
||||||
|
*/
|
||||||
|
|
||||||
/** File Type (ECMA 167r3 4/14.6.6)
|
/** File Type (ECMA 167r3 4/14.6.6)
|
||||||
|
|
||||||
@@ -649,11 +653,25 @@ typedef enum {
|
|||||||
|
|
||||||
/** Flags (ECMA 167r3 4/14.6.8) */
|
/** Flags (ECMA 167r3 4/14.6.8) */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ICBTAG_FLAG_AD_MASK = 0x0007,
|
ICBTAG_FLAG_AD_MASK = 0x0007, /**< "&" this to get below address
|
||||||
ICBTAG_FLAG_AD_SHORT = 0x0000,
|
flags */
|
||||||
ICBTAG_FLAG_AD_LONG = 0x0001,
|
ICBTAG_FLAG_AD_SHORT = 0x0000, /**< The allocation descriptor
|
||||||
|
field is filled with
|
||||||
|
short_ad's. If the
|
||||||
|
offset is beyond the
|
||||||
|
current extent, look for
|
||||||
|
the next extent. */
|
||||||
|
ICBTAG_FLAG_AD_LONG = 0x0001, /**< The allocation descriptor
|
||||||
|
field is filled with
|
||||||
|
long_ad's If the offset
|
||||||
|
is beyond the current
|
||||||
|
extent, look for the next
|
||||||
|
extent. */
|
||||||
ICBTAG_FLAG_AD_EXTENDED = 0x0002,
|
ICBTAG_FLAG_AD_EXTENDED = 0x0002,
|
||||||
ICBTAG_FLAG_AD_IN_ICB = 0x0003,
|
ICBTAG_FLAG_AD_IN_ICB = 0x0003, /**< This type means that the
|
||||||
|
file *data* is stored in
|
||||||
|
the allocation descriptor
|
||||||
|
field of the file entry. */
|
||||||
ICBTAG_FLAG_SORTED = 0x0008,
|
ICBTAG_FLAG_SORTED = 0x0008,
|
||||||
ICBTAG_FLAG_NONRELOCATABLE = 0x0010,
|
ICBTAG_FLAG_NONRELOCATABLE = 0x0010,
|
||||||
ICBTAG_FLAG_ARCHIVE = 0x0020,
|
ICBTAG_FLAG_ARCHIVE = 0x0020,
|
||||||
@@ -978,15 +996,11 @@ PRAGMA_END_PACKED
|
|||||||
allow one refer to the enumeration value names in the typedefs
|
allow one refer to the enumeration value names in the typedefs
|
||||||
above in a debugger and in debugger expressions.
|
above in a debugger and in debugger expressions.
|
||||||
*/
|
*/
|
||||||
typedef union
|
extern tag_id_t debug_tagid;
|
||||||
{
|
extern file_characteristics_t debug_file_characteristics;
|
||||||
tag_id_t debug_tagid;
|
extern icbtag_file_type_enum_t debug_icbtag_file_type_enum;
|
||||||
file_characteristics_t debug_file_characteristics;
|
extern icbtag_flag_enum_t debug_flag_enum;
|
||||||
icbtag_file_type_enum_t debug_icbtag_file_type_enum;
|
extern ecma_167_enum1_t debug_ecma_167_enum1;
|
||||||
icbtag_flag_enum_t debug_flag_enum;
|
extern ecma_167_timezone_enum_t debug_ecma_167_timezone_enum;
|
||||||
ecma_167_enum1_t debug_ecma_167_enum1;
|
|
||||||
ecma_167_timezone_enum_t debug_ecma_167_timezone_enum;
|
|
||||||
} debug_ecma167_t;
|
|
||||||
extern debug_ecma167_t debug_ecma_167;
|
|
||||||
|
|
||||||
#endif /* _ECMA_167_H */
|
#endif /* _ECMA_167_H */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: udf.c,v 1.10 2006/04/16 02:34:10 rocky Exp $
|
$Id: udf.c,v 1.11 2006/04/17 03:32:38 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
|
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
|
||||||
|
|
||||||
@@ -35,8 +35,12 @@
|
|||||||
to the enumeration value names in the typedefs above in a debugger
|
to the enumeration value names in the typedefs above in a debugger
|
||||||
and debugger expressions
|
and debugger expressions
|
||||||
*/
|
*/
|
||||||
extern debug_ecma167_t debug_ecma_167;
|
tag_id_t debug_tagid;
|
||||||
|
file_characteristics_t debug_file_characteristics;
|
||||||
|
icbtag_file_type_enum_t debug_icbtag_file_type_enum;
|
||||||
|
icbtag_flag_enum_t debug_flag_enum;
|
||||||
|
ecma_167_enum1_t debug_ecma_167_enum1;
|
||||||
|
ecma_167_timezone_enum_t debug_ecma_167_timezone_enum;
|
||||||
udf_enum1_t debug_udf_enum1;
|
udf_enum1_t debug_udf_enum1;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: udf_file.c,v 1.11 2006/04/16 02:34:10 rocky Exp $
|
$Id: udf_file.c,v 1.12 2006/04/17 03:32:38 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
||||||
|
|
||||||
@@ -29,7 +29,13 @@
|
|||||||
|
|
||||||
#include <stdio.h> /* Remove when adding cdio/logging.h */
|
#include <stdio.h> /* Remove when adding cdio/logging.h */
|
||||||
|
|
||||||
|
/* Useful defines */
|
||||||
|
|
||||||
#define MIN(a, b) (a<b) ? (a) : (b)
|
#define MIN(a, b) (a<b) ? (a) : (b)
|
||||||
|
#define CEILING(x, y) ((x+(y-1))/y)
|
||||||
|
|
||||||
|
#define GETICB(offset) \
|
||||||
|
&p_udf_fe->alloc_descs[offset]
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
udf_get_filename(const udf_dirent_t *p_udf_dirent)
|
udf_get_filename(const udf_dirent_t *p_udf_dirent)
|
||||||
@@ -39,6 +45,8 @@ udf_get_filename(const udf_dirent_t *p_udf_dirent)
|
|||||||
return p_udf_dirent->psz_name;
|
return p_udf_dirent->psz_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get UDF File Entry. However we do NOT get the variable-length extended
|
||||||
|
attributes. */
|
||||||
bool
|
bool
|
||||||
udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
|
udf_get_file_entry(const udf_dirent_t *p_udf_dirent,
|
||||||
/*out*/ udf_file_entry_t *p_udf_fe)
|
/*out*/ udf_file_entry_t *p_udf_fe)
|
||||||
@@ -96,6 +104,112 @@ udf_is_dir(const udf_dirent_t *p_udf_dirent)
|
|||||||
return p_udf_dirent->b_dir;
|
return p_udf_dirent->b_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate a file offset into a logical block and then into a physical
|
||||||
|
* block.
|
||||||
|
*/
|
||||||
|
static lba_t
|
||||||
|
offset_to_lba(const udf_dirent_t *p_udf_dirent, off_t i_offset,
|
||||||
|
/*out*/ lba_t *pi_lba, /*out*/ uint32_t *pi_max_size)
|
||||||
|
{
|
||||||
|
udf_t *p_udf = p_udf_dirent->p_udf;
|
||||||
|
const udf_file_entry_t *p_udf_fe = (udf_file_entry_t *)
|
||||||
|
&p_udf_dirent->fe;
|
||||||
|
const udf_icbtag_t *p_icb_tag = &p_udf_fe->icb_tag;
|
||||||
|
const uint16_t strat_type= uint16_from_le(p_icb_tag->strat_type);
|
||||||
|
|
||||||
|
switch (strat_type) {
|
||||||
|
case 4096:
|
||||||
|
printf("Cannot deal with strategy4096 yet!\n");
|
||||||
|
return CDIO_INVALID_LBA;
|
||||||
|
break;
|
||||||
|
case ICBTAG_STRATEGY_TYPE_4:
|
||||||
|
{
|
||||||
|
uint32_t icblen = 0;
|
||||||
|
lba_t lsector;
|
||||||
|
int ad_offset, ad_num = 0;
|
||||||
|
uint16_t addr_ilk = uint16_from_le(p_icb_tag->flags&ICBTAG_FLAG_AD_MASK);
|
||||||
|
|
||||||
|
switch (addr_ilk) {
|
||||||
|
case ICBTAG_FLAG_AD_SHORT:
|
||||||
|
{
|
||||||
|
udf_short_ad_t *p_icb;
|
||||||
|
/*
|
||||||
|
* The allocation descriptor field is filled with short_ad's.
|
||||||
|
* If the offset is beyond the current extent, look for the
|
||||||
|
* next extent.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
i_offset -= icblen;
|
||||||
|
ad_offset = sizeof(udf_short_ad_t) * ad_num;
|
||||||
|
if (ad_offset > uint32_from_le(p_udf_fe->i_alloc_descs)) {
|
||||||
|
printf("File offset out of bounds\n");
|
||||||
|
return CDIO_INVALID_LBA;
|
||||||
|
}
|
||||||
|
p_icb = (udf_short_ad_t *)
|
||||||
|
GETICB( uint32_from_le(p_udf_fe->i_extended_attr)
|
||||||
|
+ ad_offset );
|
||||||
|
icblen = p_icb->len;
|
||||||
|
ad_num++;
|
||||||
|
} while(i_offset >= icblen);
|
||||||
|
|
||||||
|
lsector = (i_offset / UDF_BLOCKSIZE) + p_icb->pos;
|
||||||
|
|
||||||
|
*pi_max_size = p_icb->len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ICBTAG_FLAG_AD_LONG:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The allocation descriptor field is filled with long_ad's
|
||||||
|
* If the i_offset is beyond the current extent, look for the
|
||||||
|
* next extent.
|
||||||
|
*/
|
||||||
|
udf_long_ad_t *p_icb;
|
||||||
|
do {
|
||||||
|
i_offset -= icblen;
|
||||||
|
ad_offset = sizeof(udf_long_ad_t) * ad_num;
|
||||||
|
if (ad_offset > uint32_from_le(p_udf_fe->i_alloc_descs)) {
|
||||||
|
printf("File offset out of bounds\n");
|
||||||
|
return CDIO_INVALID_LBA;
|
||||||
|
}
|
||||||
|
p_icb = (udf_long_ad_t *)
|
||||||
|
GETICB( uint32_from_le(p_udf_fe->i_extended_attr)
|
||||||
|
+ ad_offset );
|
||||||
|
icblen = p_icb->len;
|
||||||
|
ad_num++;
|
||||||
|
} while(i_offset >= icblen);
|
||||||
|
|
||||||
|
lsector = (i_offset / UDF_BLOCKSIZE) +
|
||||||
|
uint32_from_le(((udf_long_ad_t *)(p_icb))->loc.lba);
|
||||||
|
|
||||||
|
*pi_max_size = p_icb->len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ICBTAG_FLAG_AD_IN_ICB:
|
||||||
|
/*
|
||||||
|
* This type means that the file *data* is stored in the
|
||||||
|
* allocation descriptor field of the file entry.
|
||||||
|
*/
|
||||||
|
*pi_max_size = 0;
|
||||||
|
printf("Don't know how to data in ICB handle yet\n");
|
||||||
|
|
||||||
|
case ICBTAG_FLAG_AD_EXTENDED:
|
||||||
|
printf("Don't know how to handle extended addresses yet\n");
|
||||||
|
default:
|
||||||
|
printf("Unsupported allocation descriptor %d\n", addr_ilk);
|
||||||
|
return CDIO_INVALID_LBA;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pi_lba = lsector + p_udf->i_part_start;
|
||||||
|
return *pi_lba;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("Unknown strategy type %d\n", strat_type);
|
||||||
|
return DRIVER_OP_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Attempts to read up to count bytes from UDF directory entry
|
Attempts to read up to count bytes from UDF directory entry
|
||||||
p_udf_dirent into the buffer starting at buf. buf should be a
|
p_udf_dirent into the buffer starting at buf. buf should be a
|
||||||
@@ -113,39 +227,26 @@ udf_read_block(const udf_dirent_t *p_udf_dirent, void * buf, size_t count)
|
|||||||
{
|
{
|
||||||
if (count == 0) return 0;
|
if (count == 0) return 0;
|
||||||
else {
|
else {
|
||||||
/* FIXME this code seems a bit convoluted. */
|
|
||||||
udf_t *p_udf = p_udf_dirent->p_udf;
|
|
||||||
const udf_file_entry_t *p_udf_fe = (udf_file_entry_t *) p_udf_dirent->data;
|
|
||||||
driver_return_code_t ret;
|
driver_return_code_t ret;
|
||||||
const unsigned long int i_file_length = udf_get_file_length(p_udf_dirent);
|
uint32_t i_max_size;
|
||||||
|
udf_t *p_udf = p_udf_dirent->p_udf;
|
||||||
if (0 == p_udf->i_position) {
|
lba_t i_lba = offset_to_lba(p_udf_dirent, p_udf->i_position, &i_lba,
|
||||||
ret = udf_read_sectors(p_udf, p_udf_dirent->data,
|
&i_max_size);
|
||||||
p_udf_dirent->fe.unique_ID, 1);
|
if (i_lba != CDIO_INVALID_LBA) {
|
||||||
if (ret != DRIVER_OP_SUCCESS) return DRIVER_OP_ERROR;
|
uint32_t i_max_blocks = CEILING(i_max_size, UDF_BLOCKSIZE);
|
||||||
}
|
if ( i_max_blocks < count ) {
|
||||||
{
|
|
||||||
if (!udf_checktag(&p_udf_fe->tag, TAGID_FILE_ENTRY)) {
|
|
||||||
uint32_t i_lba_start, i_lba_end;
|
|
||||||
udf_get_lba( p_udf_fe, &i_lba_start, &i_lba_end);
|
|
||||||
|
|
||||||
/* set i_lba_start to position of where we last left off. */
|
|
||||||
i_lba_start += (p_udf->i_position / UDF_BLOCKSIZE);
|
|
||||||
|
|
||||||
if ( (i_lba_end - i_lba_start+1) < count ) {
|
|
||||||
printf("Warning: don't know how to handle yet\n" );
|
printf("Warning: don't know how to handle yet\n" );
|
||||||
count = i_lba_end - i_lba_start+1;
|
count = i_max_blocks;
|
||||||
} else {
|
}
|
||||||
const uint32_t i_lba = p_udf->i_part_start+i_lba_start;
|
|
||||||
ret = udf_read_sectors(p_udf, buf, i_lba, count);
|
ret = udf_read_sectors(p_udf, buf, i_lba, count);
|
||||||
if (DRIVER_OP_SUCCESS == ret) {
|
if (DRIVER_OP_SUCCESS == ret) {
|
||||||
ssize_t i_read_len = MIN(i_file_length, count * UDF_BLOCKSIZE);
|
ssize_t i_read_len = MIN(i_max_size, count * UDF_BLOCKSIZE);
|
||||||
p_udf->i_position += i_read_len;
|
p_udf->i_position += i_read_len;
|
||||||
return i_read_len;
|
return i_read_len;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
|
} else {
|
||||||
|
return DRIVER_OP_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: udf_fs.c,v 1.19 2006/04/15 03:05:14 rocky Exp $
|
$Id: udf_fs.c,v 1.20 2006/04/17 03:32:38 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
Copyright (C) 2005, 2006 Rocky Bernstein <rocky@cpan.org>
|
||||||
|
|
||||||
@@ -154,6 +154,7 @@ udf_get_lba(const udf_file_entry_t *p_udf_fe,
|
|||||||
switch (p_udf_fe->icb_tag.flags & ICBTAG_FLAG_AD_MASK) {
|
switch (p_udf_fe->icb_tag.flags & ICBTAG_FLAG_AD_MASK) {
|
||||||
case ICBTAG_FLAG_AD_SHORT:
|
case ICBTAG_FLAG_AD_SHORT:
|
||||||
{
|
{
|
||||||
|
/* The allocation descriptor field is filled with short_ad's. */
|
||||||
udf_short_ad_t *p_ad = (udf_short_ad_t *)
|
udf_short_ad_t *p_ad = (udf_short_ad_t *)
|
||||||
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
|
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
|
||||||
|
|
||||||
@@ -165,6 +166,7 @@ udf_get_lba(const udf_file_entry_t *p_udf_fe,
|
|||||||
break;
|
break;
|
||||||
case ICBTAG_FLAG_AD_LONG:
|
case ICBTAG_FLAG_AD_LONG:
|
||||||
{
|
{
|
||||||
|
/* The allocation descriptor field is filled with long_ad's */
|
||||||
udf_long_ad_t *p_ad = (udf_long_ad_t *)
|
udf_long_ad_t *p_ad = (udf_long_ad_t *)
|
||||||
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
|
(p_udf_fe->ext_attr + p_udf_fe->i_extended_attr);
|
||||||
|
|
||||||
@@ -193,6 +195,11 @@ udf_get_lba(const udf_file_entry_t *p_udf_fe,
|
|||||||
|
|
||||||
#define udf_PATH_DELIMITERS "/\\"
|
#define udf_PATH_DELIMITERS "/\\"
|
||||||
|
|
||||||
|
/* Searches p_udf_dirent a directory entry called psz_token.
|
||||||
|
Note p_udf_dirent is continuously updated. If the entry is
|
||||||
|
not found p_udf_dirent is useless and thus the caller should
|
||||||
|
not use it afterwards.
|
||||||
|
*/
|
||||||
static
|
static
|
||||||
udf_dirent_t *
|
udf_dirent_t *
|
||||||
udf_ff_traverse(udf_dirent_t *p_udf_dirent, char *psz_token)
|
udf_ff_traverse(udf_dirent_t *p_udf_dirent, char *psz_token)
|
||||||
@@ -216,6 +223,7 @@ udf_ff_traverse(udf_dirent_t *p_udf_dirent, char *psz_token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(p_udf_dirent->psz_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,8 +241,18 @@ udf_fopen(udf_dirent_t *p_udf_root, const char *psz_name)
|
|||||||
|
|
||||||
strncpy(tokenline, psz_name, udf_MAX_PATHLEN);
|
strncpy(tokenline, psz_name, udf_MAX_PATHLEN);
|
||||||
psz_token = strtok(tokenline, udf_PATH_DELIMITERS);
|
psz_token = strtok(tokenline, udf_PATH_DELIMITERS);
|
||||||
if (psz_token)
|
if (psz_token) {
|
||||||
p_udf_file = udf_ff_traverse(p_udf_root, psz_token);
|
/*** FIXME??? udf_dirent can be variable size due to the
|
||||||
|
extended attributes and descriptors. Given that, is this
|
||||||
|
correct?
|
||||||
|
*/
|
||||||
|
udf_dirent_t *p_udf_dirent =
|
||||||
|
udf_new_dirent(&p_udf_root->fe, p_udf_root->p_udf,
|
||||||
|
p_udf_root->psz_name, p_udf_root->b_dir,
|
||||||
|
p_udf_root->b_parent);
|
||||||
|
p_udf_file = udf_ff_traverse(p_udf_dirent, psz_token);
|
||||||
|
udf_dirent_free(p_udf_dirent);
|
||||||
|
}
|
||||||
else if ( 0 == strncmp("/", psz_name, sizeof("/")) ) {
|
else if ( 0 == strncmp("/", psz_name, sizeof("/")) ) {
|
||||||
return udf_new_dirent(&p_udf_root->fe, p_udf_root->p_udf,
|
return udf_new_dirent(&p_udf_root->fe, p_udf_root->p_udf,
|
||||||
p_udf_root->psz_name, p_udf_root->b_dir,
|
p_udf_root->psz_name, p_udf_root->b_dir,
|
||||||
@@ -268,9 +286,13 @@ static udf_dirent_t *
|
|||||||
udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
|
udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
|
||||||
const char *psz_name, bool b_dir, bool b_parent)
|
const char *psz_name, bool b_dir, bool b_parent)
|
||||||
{
|
{
|
||||||
udf_dirent_t *p_udf_dirent =
|
const unsigned int i_alloc_size = p_udf_fe->i_alloc_descs
|
||||||
(udf_dirent_t *) calloc(1, sizeof(udf_dirent_t));
|
+ p_udf_fe->i_extended_attr;;
|
||||||
|
|
||||||
|
udf_dirent_t *p_udf_dirent = (udf_dirent_t *)
|
||||||
|
calloc(1, sizeof(udf_dirent_t) + i_alloc_size);
|
||||||
if (!p_udf_dirent) return NULL;
|
if (!p_udf_dirent) return NULL;
|
||||||
|
|
||||||
p_udf_dirent->psz_name = strdup(psz_name);
|
p_udf_dirent->psz_name = strdup(psz_name);
|
||||||
p_udf_dirent->b_dir = b_dir;
|
p_udf_dirent->b_dir = b_dir;
|
||||||
p_udf_dirent->b_parent = b_parent;
|
p_udf_dirent->b_parent = b_parent;
|
||||||
@@ -278,7 +300,8 @@ udf_new_dirent(udf_file_entry_t *p_udf_fe, udf_t *p_udf,
|
|||||||
p_udf_dirent->i_part_start = p_udf->i_part_start;
|
p_udf_dirent->i_part_start = p_udf->i_part_start;
|
||||||
p_udf_dirent->dir_left = uint64_from_le(p_udf_fe->info_len);
|
p_udf_dirent->dir_left = uint64_from_le(p_udf_fe->info_len);
|
||||||
|
|
||||||
memcpy(&(p_udf_dirent->fe), p_udf_fe, sizeof(udf_file_entry_t));
|
memcpy(&(p_udf_dirent->fe), p_udf_fe,
|
||||||
|
sizeof(udf_file_entry_t) + i_alloc_size);
|
||||||
udf_get_lba( p_udf_fe, &(p_udf_dirent->i_loc),
|
udf_get_lba( p_udf_fe, &(p_udf_dirent->i_loc),
|
||||||
&(p_udf_dirent->i_loc_end) );
|
&(p_udf_dirent->i_loc_end) );
|
||||||
return p_udf_dirent;
|
return p_udf_dirent;
|
||||||
@@ -639,7 +662,9 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
|
|||||||
udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start
|
udf_read_sectors(p_udf, p_udf_fe, p_udf->i_part_start
|
||||||
+ p_udf_dirent->fid->icb.loc.lba, 1);
|
+ p_udf_dirent->fid->icb.loc.lba, 1);
|
||||||
|
|
||||||
memcpy(&(p_udf_dirent->fe), p_udf_fe, sizeof(udf_file_entry_t));
|
memcpy(&(p_udf_dirent->fe), p_udf_fe,
|
||||||
|
sizeof(udf_file_entry_t) + p_udf_fe->i_alloc_descs
|
||||||
|
+ p_udf_fe->i_extended_attr );
|
||||||
|
|
||||||
if (strlen(p_udf_dirent->psz_name) < i_len)
|
if (strlen(p_udf_dirent->psz_name) < i_len)
|
||||||
p_udf_dirent->psz_name = (char *)
|
p_udf_dirent->psz_name = (char *)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: udf_fs.h,v 1.1 2006/04/11 05:47:58 rocky Exp $
|
$Id: udf_fs.h,v 1.2 2006/04/17 03:32:38 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
Copyright (C) 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#ifndef __CDIO_UDF_FS_H__
|
#ifndef __CDIO_UDF_FS_H__
|
||||||
#define __CDIO_UDF_FS_H__
|
#define __CDIO_UDF_FS_H__
|
||||||
|
|
||||||
|
#include <cdio/ecma_167.h>
|
||||||
/**
|
/**
|
||||||
* Check the descriptor tag for both the correct id and correct checksum.
|
* Check the descriptor tag for both the correct id and correct checksum.
|
||||||
* Return zero if all is good, -1 if not.
|
* Return zero if all is good, -1 if not.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
$Id: udf_private.h,v 1.10 2006/04/16 02:34:10 rocky Exp $
|
$Id: udf_private.h,v 1.11 2006/04/17 03:32:38 rocky Exp $
|
||||||
|
|
||||||
Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
Copyright (C) 2005, 2006 Rocky Bernstein <rockyb@users.sourceforge.net>
|
||||||
|
|
||||||
@@ -58,9 +58,10 @@ struct udf_dirent_s
|
|||||||
uint32_t i_loc, i_loc_end;
|
uint32_t i_loc, i_loc_end;
|
||||||
uint64_t dir_left;
|
uint64_t dir_left;
|
||||||
uint8_t *sector;
|
uint8_t *sector;
|
||||||
udf_file_entry_t fe;
|
|
||||||
udf_fileid_desc_t *fid;
|
udf_fileid_desc_t *fid;
|
||||||
uint8_t data[UDF_BLOCKSIZE];
|
|
||||||
|
/* This field has to come last because it is variable in length. */
|
||||||
|
udf_file_entry_t fe;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool udf_get_lba(const udf_file_entry_t *p_udf_fe,
|
bool udf_get_lba(const udf_file_entry_t *p_udf_fe,
|
||||||
|
|||||||
Reference in New Issue
Block a user