2008-02-24 Bean <bean123ch@gmail.com>
* fs/iso9660.c (GRUB_ISO9660_VOLDESC_BOOT): New macro. (GRUB_ISO9660_VOLDESC_PRIMARY): Likewise. (GRUB_ISO9660_VOLDESC_SUPP): Likewise. (GRUB_ISO9660_VOLDESC_PART): Likewise. (GRUB_ISO9660_VOLDESC_END): Likewise. (grub_iso9660_primary_voldesc): New member escape. (grub_iso9660_data): New member joliet. (grub_iso9660_convert_string): New function. (grub_iso9660_mount): Detect joliet extension. (grub_iso9660_iterate_dir): Convert filename when joliet is detected. (grub_iso9660_iso9660_label): Likewise. * conf/common.rmk (pkgdata_MODULES): Add udf.mod. (grub_setup_SOURCES): Add fs/udf.c. (grub_fstest_SOURCES): Likewise. (udf_mod_SOURCES): New variable. (udf_mod_CFLAGS): Likewise. (udf_mod_LDFLAGS): Likewise. * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/udf.c. (grub_emu_SOURCES): Likewise. * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. * fs/udf.c: New file.
This commit is contained in:
parent
8a594a17c7
commit
0d16e571f1
15 changed files with 1185 additions and 74 deletions
119
fs/iso9660.c
119
fs/iso9660.c
|
@ -38,6 +38,12 @@
|
|||
#define GRUB_ISO9660_RR_DOT 2
|
||||
#define GRUB_ISO9660_RR_DOTDOT 4
|
||||
|
||||
#define GRUB_ISO9660_VOLDESC_BOOT 0
|
||||
#define GRUB_ISO9660_VOLDESC_PRIMARY 1
|
||||
#define GRUB_ISO9660_VOLDESC_SUPP 2
|
||||
#define GRUB_ISO9660_VOLDESC_PART 3
|
||||
#define GRUB_ISO9660_VOLDESC_END 255
|
||||
|
||||
/* The head of a volume descriptor. */
|
||||
struct grub_iso9660_voldesc
|
||||
{
|
||||
|
@ -67,11 +73,13 @@ struct grub_iso9660_primary_voldesc
|
|||
struct grub_iso9660_voldesc voldesc;
|
||||
grub_uint8_t unused1[33];
|
||||
grub_uint8_t volname[32];
|
||||
grub_uint8_t unused2[60];
|
||||
grub_uint8_t unused2[16];
|
||||
grub_uint8_t escape[32];
|
||||
grub_uint8_t unused3[12];
|
||||
grub_uint32_t path_table_size;
|
||||
grub_uint8_t unused3[4];
|
||||
grub_uint8_t unused4[4];
|
||||
grub_uint32_t path_table;
|
||||
grub_uint8_t unused4[12];
|
||||
grub_uint8_t unused5[12];
|
||||
struct grub_iso9660_dir rootdir;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
@ -115,6 +123,7 @@ struct grub_iso9660_data
|
|||
unsigned int length;
|
||||
int rockridge;
|
||||
int susp_skip;
|
||||
int joliet;
|
||||
};
|
||||
|
||||
struct grub_fshelp_node
|
||||
|
@ -197,6 +206,23 @@ grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
grub_iso9660_convert_string (grub_uint16_t *us, int len)
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
p = grub_malloc (len * 4 + 1);
|
||||
if (! p)
|
||||
return p;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
us[i] = grub_be_to_cpu16 (us[i]);
|
||||
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) p, us, len) = '\0';
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct grub_iso9660_data *
|
||||
grub_iso9660_mount (grub_disk_t disk)
|
||||
|
@ -207,6 +233,8 @@ grub_iso9660_mount (grub_disk_t disk)
|
|||
int sua_size;
|
||||
char *sua;
|
||||
struct grub_iso9660_susp_entry *entry;
|
||||
struct grub_iso9660_primary_voldesc voldesc;
|
||||
int block;
|
||||
|
||||
auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
|
||||
|
||||
|
@ -226,24 +254,49 @@ grub_iso9660_mount (grub_disk_t disk)
|
|||
if (! data)
|
||||
return 0;
|
||||
|
||||
/* Read the superblock. */
|
||||
if (grub_disk_read (disk, 16 << GRUB_ISO9660_LOG2_BLKSZ, 0,
|
||||
sizeof (struct grub_iso9660_primary_voldesc),
|
||||
(char *) &data->voldesc))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (grub_strncmp ((char *) data->voldesc.voldesc.magic, "CD001", 5) != 0)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->disk = disk;
|
||||
data->rockridge = 0;
|
||||
|
||||
data->joliet = 0;
|
||||
|
||||
block = 16;
|
||||
do
|
||||
{
|
||||
int copy_voldesc = 0;
|
||||
|
||||
/* Read the superblock. */
|
||||
if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0,
|
||||
sizeof (struct grub_iso9660_primary_voldesc),
|
||||
(char *) &voldesc))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY)
|
||||
copy_voldesc = 1;
|
||||
else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) &&
|
||||
(voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) &&
|
||||
((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */
|
||||
(voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */
|
||||
(voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */
|
||||
{
|
||||
copy_voldesc = 1;
|
||||
data->joliet = 1;
|
||||
}
|
||||
|
||||
if (copy_voldesc)
|
||||
grub_memcpy((char *) &data->voldesc, (char *) &voldesc,
|
||||
sizeof (struct grub_iso9660_primary_voldesc));
|
||||
|
||||
block++;
|
||||
} while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END);
|
||||
|
||||
/* Read the system use area and test it to see if SUSP is
|
||||
supported. */
|
||||
if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
||||
|
@ -254,14 +307,6 @@ grub_iso9660_mount (grub_disk_t disk)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
|
||||
<< GRUB_ISO9660_LOG2_BLKSZ), 0,
|
||||
sizeof (rootdir), (char *) &rootdir))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sua_pos = (sizeof (rootdir) + rootdir.namelen
|
||||
+ (rootdir.namelen % 2) - 1);
|
||||
sua_size = rootdir.len - sua_pos;
|
||||
|
@ -572,6 +617,20 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
|||
filename = name;
|
||||
}
|
||||
|
||||
if (dir->data->joliet)
|
||||
{
|
||||
char *oldname;
|
||||
|
||||
oldname = filename;
|
||||
filename = grub_iso9660_convert_string
|
||||
((grub_uint16_t *) oldname, dirent.namelen >> 1);
|
||||
|
||||
if (filename_alloc)
|
||||
grub_free (oldname);
|
||||
|
||||
filename_alloc = 1;
|
||||
}
|
||||
|
||||
if (hook (filename, type, node))
|
||||
{
|
||||
if (filename_alloc)
|
||||
|
@ -740,7 +799,11 @@ grub_iso9660_label (grub_device_t device, char **label)
|
|||
|
||||
if (data)
|
||||
{
|
||||
*label = grub_strndup ((char *) data->voldesc.volname, 32);
|
||||
if (data->joliet)
|
||||
*label = grub_iso9660_convert_string
|
||||
((grub_uint16_t *) &data->voldesc.volname, 16);
|
||||
else
|
||||
*label = grub_strndup ((char *) data->voldesc.volname, 32);
|
||||
grub_free (data);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue