]> code.delx.au - refind/blobdiff - filesystems/fsw_hfs.c
Added correct filesystem name detection to HFS+ driver.
[refind] / filesystems / fsw_hfs.c
index 59823c6e9bb197421e48b06cc9fb27f79ff9cc63..deea0f8235014b585e2bb7e8bdd2de5bb472f573 100644 (file)
@@ -215,13 +215,15 @@ HFSGetDescription(CICell ih, char *str, long strMaxLen)
 
 static fsw_status_t fsw_hfs_volume_mount(struct fsw_hfs_volume *vol)
 {
-    fsw_status_t           status, rv;
-    void                  *buffer = NULL;
-    HFSPlusVolumeHeader   *voldesc;
-    fsw_u32                blockno;
-    struct fsw_string      s;
-  HFSMasterDirectoryBlock* mdb;
-  UINTN i;
+    fsw_status_t              status, rv;
+    void                      *buffer = NULL;
+    HFSPlusVolumeHeader       *voldesc;
+    fsw_u32                   blockno;
+    struct fsw_string         s;
+    HFSMasterDirectoryBlock*  mdb;
+    fsw_u32 firstLeafNum;
+    fsw_u64 catfOffset;
+    fsw_u8 cbuff[sizeof (BTNodeDescriptor) + sizeof (HFSPlusCatalogKey)];
 
     rv = FSW_UNSUPPORTED;
 
@@ -253,14 +255,12 @@ static fsw_status_t fsw_hfs_volume_mount(struct fsw_hfs_volume *vol)
         {
             if (vol->hfs_kind == 0)
             {
-    //            DPRINT("found HFS+\n");
+//                DPRINT("found HFS+\n");
                 vol->hfs_kind = FSW_HFS_PLUS;
             }
         }
         else if (signature == kHFSSigWord) // 'BD'
         {
-//            HFSMasterDirectoryBlock* mdb = (HFSMasterDirectoryBlock*)buffer;
-//VolumeName = mdb->drVN 28bytes
             if (be16_to_cpu(mdb->drEmbedSigWord) == kHFSPlusSigWord)
             {
                 DPRINT("found HFS+ inside HFS, untested\n");
@@ -298,15 +298,9 @@ static fsw_status_t fsw_hfs_volume_mount(struct fsw_hfs_volume *vol)
         fsw_set_blocksize(vol, block_size, block_size);
 
         /* get volume name */
-      for (i = kHFSMaxVolumeNameChars; i > 0; i--)
-        if (mdb->drVN[i-1] != ' ')
-          break;
-      
         s.type = FSW_STRING_TYPE_ISO88591;
-        s.size = s.len = 0;
-      s.data = NULL; //&mdb->drVN; //"HFS+ volume";
-      
-       //fsw_status_t fsw_strdup_coerce(struct fsw_string *dest, int type, struct fsw_string *src)
+        s.size = s.len = kHFSMaxVolumeNameChars;
+        s.data = "HFS+ volume";
         status = fsw_strdup_coerce(&vol->g.label, vol->g.host_string_type, &s);
         CHECK(status);
 
@@ -349,6 +343,34 @@ static fsw_status_t fsw_hfs_volume_mount(struct fsw_hfs_volume *vol)
         vol->catalog_tree.root_node = be32_to_cpu (tree_header.rootNode);
         vol->catalog_tree.node_size = be16_to_cpu (tree_header.nodeSize);
 
+        //nms42
+        /* Take Volume Name before tree_header overwritten */
+        firstLeafNum = be32_to_cpu(tree_header.firstLeafNode);
+        catfOffset = firstLeafNum * vol->catalog_tree.node_size;
+
+        r = fsw_hfs_read_file(vol->catalog_tree.file, catfOffset, sizeof (cbuff), cbuff);
+
+        if (r == sizeof (cbuff))
+        {
+           BTNodeDescriptor* btnd;
+           HFSPlusCatalogKey* ck;
+
+           btnd = (BTNodeDescriptor*) cbuff;
+           ck = (HFSPlusCatalogKey*) (cbuff + sizeof(BTNodeDescriptor));
+           if (btnd->kind == kBTLeafNode && be32_to_cpu (ck->parentID) == kHFSRootParentID)
+           {
+              struct fsw_string vn;
+
+              vn.type = FSW_STRING_TYPE_UTF16_BE;
+              vn.len = be16_to_cpu (ck->nodeName.length);
+              vn.size = vn.len * sizeof (fsw_u16);
+              vn.data = ck->nodeName.unicode;
+              fsw_strfree (&vol->g.label);
+              status = fsw_strdup_coerce(&vol->g.label, vol->g.host_string_type, &vn);
+              CHECK(status);
+           } // if
+        } // if
+
         /* Read extents overflow file */
         r = fsw_hfs_read_file(vol->extents_tree.file,
                               sizeof (BTNodeDescriptor),