};
} GRUB_PACKED;
+struct grub_udf_pvd
+{
+ struct grub_udf_tag tag;
+ grub_uint32_t seq_num;
+ grub_uint32_t pvd_num;
+ grub_uint8_t ident[32];
+ grub_uint16_t vol_seq_num;
+ grub_uint16_t max_vol_seq_num;
+ grub_uint16_t interchange_level;
+ grub_uint16_t max_interchange_level;
+ grub_uint32_t charset_list;
+ grub_uint32_t max_charset_list;
+ grub_uint8_t volset_ident[128];
+ struct grub_udf_charspec desc_charset;
+ struct grub_udf_charspec expl_charset;
+ struct grub_udf_extent_ad vol_abstract;
+ struct grub_udf_extent_ad vol_copyright;
+ struct grub_udf_regid app_ident;
+ struct grub_udf_timestamp recording_time;
+ struct grub_udf_regid imp_ident;
+ grub_uint8_t imp_use[64];
+ grub_uint32_t pred_vds_loc;
+ grub_uint16_t flags;
+ grub_uint8_t reserved[22];
+} GRUB_PACKED;
+
struct grub_udf_lvd
{
struct grub_udf_tag tag;
struct grub_udf_data
{
grub_disk_t disk;
+ struct grub_udf_pvd pvd;
struct grub_udf_lvd lvd;
struct grub_udf_pd pds[GRUB_UDF_MAX_PDS];
struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS];
}
tag.tag_ident = U16 (tag.tag_ident);
- if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
+ if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PVD)
+ {
+ if (grub_disk_read (disk, block << lbshift, 0,
+ sizeof (struct grub_udf_pvd),
+ &data->pvd))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem");
+ goto fail;
+ }
+ }
+ else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD)
{
if (data->npd >= GRUB_UDF_MAX_PDS)
{
return grub_errno;
}
+static char *
+gen_uuid_from_volset (char *volset_ident)
+{
+ grub_size_t i;
+ grub_size_t len;
+ grub_size_t nonhexpos;
+ grub_uint8_t buf[17];
+ char *uuid;
+
+ len = grub_strlen (volset_ident);
+ if (len < 8)
+ return NULL;
+
+ uuid = grub_malloc (17);
+ if (!uuid)
+ return NULL;
+
+ if (len > 16)
+ len = 16;
+
+ grub_memset (buf, 0, sizeof (buf));
+ grub_memcpy (buf, volset_ident, len);
+
+ nonhexpos = 16;
+ for (i = 0; i < 16; ++i)
+ {
+ if (!grub_isxdigit (buf[i]))
+ {
+ nonhexpos = i;
+ break;
+ }
+ }
+
+ if (nonhexpos < 8)
+ {
+ grub_snprintf (uuid, 17, "%02x%02x%02x%02x%02x%02x%02x%02x",
+ buf[0], buf[1], buf[2], buf[3],
+ buf[4], buf[5], buf[6], buf[7]);
+ }
+ else if (nonhexpos < 16)
+ {
+ for (i = 0; i < 8; ++i)
+ uuid[i] = grub_tolower (buf[i]);
+ grub_snprintf (uuid+8, 9, "%02x%02x%02x%02x",
+ buf[8], buf[9], buf[10], buf[11]);
+ }
+ else
+ {
+ for (i = 0; i < 16; ++i)
+ uuid[i] = grub_tolower (buf[i]);
+ uuid[16] = 0;
+ }
+
+ return uuid;
+}
+
+static grub_err_t
+grub_udf_uuid (grub_device_t device, char **uuid)
+{
+ char *volset_ident;
+ struct grub_udf_data *data;
+ data = grub_udf_mount (device->disk);
+
+ if (data)
+ {
+ volset_ident = read_dstring (data->pvd.volset_ident, sizeof (data->pvd.volset_ident));
+ if (volset_ident)
+ {
+ *uuid = gen_uuid_from_volset (volset_ident);
+ grub_free (volset_ident);
+ }
+ else
+ *uuid = 0;
+ grub_free (data);
+ }
+ else
+ *uuid = 0;
+
+ return grub_errno;
+}
+
static struct grub_fs grub_udf_fs = {
.name = "udf",
.dir = grub_udf_dir,
.read = grub_udf_read,
.close = grub_udf_close,
.label = grub_udf_label,
+ .uuid = grub_udf_uuid,
#ifdef GRUB_UTIL
.reserved_first_sector = 1,
.blocklist_install = 1,