diff --git a/ChangeLog b/ChangeLog
index 2cf8f8f..e7e8530 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-05-03  Michael Scherer <misc@mandriva.org>
+
+	* fs/hfsplus.c: Complete support of hfs+ and hfsx, by doing
+	case insensitive comparaison when needed ( ie for hfsplus, and depending
+	on some settings for hfsx, found in the header )
+
 2009-05-03  Bean  <bean123ch@gmail.com> Vladimir Serbinenko <phcoder@gmail.com>
 
 	FreeBSD 64-bit support
diff --git a/fs/hfsplus.c b/fs/hfsplus.c
index 82ec880..8950b57 100644
--- a/fs/hfsplus.c
+++ b/fs/hfsplus.c
@@ -98,6 +98,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.  */
@@ -163,6 +170,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
 {
@@ -223,6 +233,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;
 };
 
 #ifndef GRUB_UTIL
@@ -465,6 +476,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),
@@ -696,6 +708,20 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
 }
 
 static int
+grub_hfsplus_is_case_insentive (struct grub_hfsplus_data *data)
+{
+  switch (grub_be_to_cpu16 (data->volheader.magic))
+    {
+      case GRUB_HFSPLUS_MAGIC:
+        return 1;
+      case GRUB_HFSPLUSX_MAGIC:
+        return data->catalog_cmp_key == GRUB_HFSPLUSX_CASEFOLDING;
+      default:
+        return 0;
+    }
+}
+
+static int
 grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
 			  int NESTED_FUNC_ATTR
 			  (*hook) (const char *filename,
@@ -703,6 +729,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
 				   grub_fshelp_node_t node))
 {
   int ret = 0;
+  int fs_case_insensitive = grub_hfsplus_is_case_insentive(dir->data);
   
   auto int list_nodes (void *record);
   int list_nodes (void *record)
@@ -773,7 +800,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 (fs_case_insensitive)
+          type |= GRUB_FSHELP_CASE_INSENSITIVE;
 
       /* Only accept valid nodes.  */
       if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen))
