Read label on HFS+.
* grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function. (grub_hfsplus_btree_search): Fix types. (grub_hfsplus_label): Implement.
This commit is contained in:
parent
e9cc6b7b0e
commit
67e2bd718e
2 changed files with 88 additions and 7 deletions
|
@ -1,3 +1,11 @@
|
|||
2011-10-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Read label on HFS+.
|
||||
|
||||
* grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function.
|
||||
(grub_hfsplus_btree_search): Fix types.
|
||||
(grub_hfsplus_label): Implement.
|
||||
|
||||
2011-10-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak.
|
||||
|
|
|
@ -553,6 +553,25 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya,
|
|||
return diff;
|
||||
}
|
||||
|
||||
/* Compare the on disk catalog key KEYA with the catalog key we are
|
||||
looking for (KEYB). */
|
||||
static int
|
||||
grub_hfsplus_cmp_catkey_id (struct grub_hfsplus_key *keya,
|
||||
struct grub_hfsplus_key_internal *keyb)
|
||||
{
|
||||
struct grub_hfsplus_catkey *catkey_a = &keya->catkey;
|
||||
struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey;
|
||||
|
||||
/* Safe unsigned comparison */
|
||||
grub_uint32_t aparent = grub_be_to_cpu32 (catkey_a->parent);
|
||||
if (aparent > catkey_b->parent)
|
||||
return 1;
|
||||
if (aparent < catkey_b->parent)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compare the on disk extent overflow key KEYA with the extent
|
||||
overflow key we are looking for (KEYB). */
|
||||
static int
|
||||
|
@ -662,7 +681,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
|||
|
||||
/* Read a node. */
|
||||
if (grub_hfsplus_read_file (&btree->file, 0,
|
||||
(long)currnode * (long)btree->nodesize,
|
||||
(grub_disk_addr_t) currnode
|
||||
* (grub_disk_addr_t) btree->nodesize,
|
||||
btree->nodesize, (char *) node) <= 0)
|
||||
{
|
||||
grub_free (node);
|
||||
|
@ -961,13 +981,66 @@ grub_hfsplus_dir (grub_device_t device, const char *path,
|
|||
|
||||
|
||||
static grub_err_t
|
||||
grub_hfsplus_label (grub_device_t device __attribute__((unused))
|
||||
, char **label __attribute__((unused)))
|
||||
grub_hfsplus_label (grub_device_t device, char **label)
|
||||
{
|
||||
/* XXX: It's not documented how to read a label. */
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"reading the label of a HFS+ "
|
||||
"partition is not implemented");
|
||||
struct grub_hfsplus_data *data;
|
||||
grub_disk_t disk = device->disk;
|
||||
struct grub_hfsplus_catkey *catkey;
|
||||
int i, label_len;
|
||||
struct grub_hfsplus_key_internal intern;
|
||||
struct grub_hfsplus_btnode *node;
|
||||
grub_disk_addr_t ptr;
|
||||
|
||||
*label = 0;
|
||||
|
||||
data = grub_hfsplus_mount (disk);
|
||||
if (!data)
|
||||
return grub_errno;
|
||||
|
||||
/* Create a key that points to the label. */
|
||||
intern.catkey.parent = 1;
|
||||
intern.catkey.name = "";
|
||||
|
||||
/* First lookup the first entry. */
|
||||
if (grub_hfsplus_btree_search (&data->catalog_tree, &intern,
|
||||
grub_hfsplus_cmp_catkey_id, &node, &ptr))
|
||||
{
|
||||
grub_free (data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
catkey = (struct grub_hfsplus_catkey *)
|
||||
grub_hfsplus_btree_recptr (&data->catalog_tree, node, 0);
|
||||
|
||||
label_len = grub_be_to_cpu16 (catkey->namelen);
|
||||
for (i = 0; i < label_len; i++)
|
||||
{
|
||||
catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]);
|
||||
|
||||
/* If the name is obviously invalid, skip this node. */
|
||||
if (catkey->name[i] == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*label = grub_malloc (label_len + 1);
|
||||
if (! *label)
|
||||
return grub_errno;
|
||||
|
||||
if (! grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name,
|
||||
label_len))
|
||||
{
|
||||
grub_free (node);
|
||||
grub_free (*label);
|
||||
grub_free (data);
|
||||
*label = 0;
|
||||
return grub_errno;
|
||||
}
|
||||
(*label)[label_len] = '\0';
|
||||
|
||||
grub_free (node);
|
||||
grub_free (data);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Get mtime. */
|
||||
|
|
Loading…
Reference in a new issue