diff --git a/ChangeLog b/ChangeLog index 60ed1a6..5b29a7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-06-05 Michael Scherer + + * fs/hfsplus.c (grub_hfsplus_iterate_dir, grub_hfsplus_is_case_sensitive): + use case sensitive comparison for hfsx when required by the filesystem + settings. + (grub_hfsplus_mount) : copy filesystem setting for case + sensitive comparison. + 2009-06-05 Vladimir Serbinenko * conf/i386-pc.rmk (efiemu_mod_CFLAGS): remove -Werror -Wall diff --git a/fs/hfsplus.c b/fs/hfsplus.c index 69794c9..1c559ee 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -99,6 +99,13 @@ struct grub_hfsplus_btheader grub_uint32_t last_leaf_node; grub_uint16_t nodesize; grub_uint16_t keysize; + grub_uint32_t total_nodes; + grub_uint32_t free_nodes; + grub_uint16_t reserved1; + grub_uint32_t clump_size; /* ignored */ + grub_uint8_t btree_type; + grub_uint8_t key_compare; + grub_uint32_t attributes; } __attribute__ ((packed)); /* The on disk layout of a catalog key. */ @@ -164,6 +171,9 @@ enum grub_hfsplus_filetype GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4 }; +#define GRUB_HFSPLUSX_BINARYCOMPARE 0xCF +#define GRUB_HFSPLUSX_CASEFOLDING 0xBC + /* Internal representation of a catalog key. */ struct grub_hfsplus_catkey_internal { @@ -224,6 +234,7 @@ struct grub_hfsplus_data /* This is the offset into the physical disk for an embedded HFS+ filesystem (one inside a plain HFS wrapper). */ int embedded_offset; + int catalog_cmp_key; }; static grub_dl_t my_mod; @@ -464,6 +475,7 @@ grub_hfsplus_mount (grub_disk_t disk) data->catalog_tree.root = grub_be_to_cpu32 (header.root); data->catalog_tree.nodesize = grub_be_to_cpu16 (header.nodesize); + data->catalog_cmp_key = header.key_compare; if (! grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, sizeof (struct grub_hfsplus_btnode), @@ -694,6 +706,16 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, } } +static inline int +grub_hfsplus_is_case_sensitive (struct grub_hfsplus_data *data) +{ + if ((grub_be_to_cpu16 (data->volheader.magic) == GRUB_HFSPLUSX_MAGIC) + && (data->catalog_cmp_key == GRUB_HFSPLUSX_BINARYCOMPARE)) + return 1; + else + return 0; +} + static int grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, int NESTED_FUNC_ATTR @@ -772,7 +794,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); /* hfs+ is case insensitive. */ - type |= GRUB_FSHELP_CASE_INSENSITIVE; + if (!grub_hfsplus_is_case_sensitive (dir->data)) + type |= GRUB_FSHELP_CASE_INSENSITIVE; /* Only accept valid nodes. */ if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))