diff --git a/tsk3/fs/fs_dir.c b/tsk3/fs/fs_dir.c
index 18378e37976bbe9abb129d958058d2581933aa66..53734d43e9a4461d18e3ec4dd397affaa7863ab7 100644
--- a/tsk3/fs/fs_dir.c
+++ b/tsk3/fs/fs_dir.c
@@ -203,6 +203,8 @@ tsk_fs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_INUM_T a_addr)
     }
 
     retval = a_fs->dir_open_meta(a_fs, &fs_dir, a_addr);
+    if (retval != TSK_OK)
+        return NULL;
 
     return fs_dir;
 }
diff --git a/tsk3/fs/hfs.c b/tsk3/fs/hfs.c
index 5b81370265f9fab6c5d13ddf3f43275ce0d3085f..6fe003bb1f9e676bcbe852f7428cec73e6c18353 100644
--- a/tsk3/fs/hfs.c
+++ b/tsk3/fs/hfs.c
@@ -933,6 +933,12 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
             (char *) &(hfs->extents_header),
             sizeof(hfs_btree_header_record), 0);
         if (cnt != sizeof(hfs_btree_header_record)) {
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_ext_find_extent_record_attr: Error reading header");
             return 0;
         }
     }
@@ -974,7 +980,12 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
         cnt = tsk_fs_attr_read(hfs->extents_attr, cur_off,
             node, nodesize, 0);
         if (cnt != nodesize) {
-            // @@@
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_ext_find_extent_record_attr: Error reading node %d at offset %"PRIuOFF, cur_node, cur_off);
             free(node);
             return 1;
         }
@@ -1008,12 +1019,17 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                 size_t rec_off;
                 hfs_ext_key *key;
 
-                // get the record offset in the node
+                // get the record offset in the node (the end of the node has record offsets)
                 rec_off =
                     tsk_getu32(fs->endian,
                     &node[nodesize - (rec + 1) * 4]);
                 if (rec_off > nodesize) {
-                    // @@@ ERROR
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_ext_find_extent_record_attr: offset of record %d in index node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off, nodesize);
+                    free(node);
+                    return 1;
                 }
                 key = (hfs_ext_key *) & node[rec_off];
                 cmp = hfs_ext_compare_keys(hfs, cnid, key);
@@ -1032,7 +1048,14 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                 /* if all keys are larger than our key, select the leftmost key */
                 if ((cmp <= 0) || (next_node == 0)) {
                     int keylen = tsk_getu16(fs->endian, key->key_len);
-                    // @@@ SANITY CHECK ON NODELEN AND rec_addr+keylen
+                    if (rec_off+keylen > nodesize) {
+                        tsk_errno = TSK_ERR_FS_GENFS;
+                        snprintf(tsk_errstr, TSK_ERRSTR_L,
+                                 "hfs_ext_find_extent_record_attr: offset and keylenth of record %d in index node %d too large (%zu vs %"PRIu16")",
+                                 rec, cur_node, rec_off+keylen, nodesize);
+                        free(node);
+                        return 1;
+                    }
                     next_node =
                         tsk_getu32(fs->endian, &node[rec_off + keylen]);
                 }
@@ -1040,8 +1063,15 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                     break;
                 }
             }
+            
+            // check if we found any relevant node
             if (next_node == 0) {
-                // @@@@
+                tsk_errno = TSK_ERR_FS_GENFS;
+                snprintf(tsk_errstr, TSK_ERRSTR_L,
+                         "hfs_ext_find_extent_record_attr: did not find any keys for %d in index node %d",
+                         cnid, cur_node);
+                free(node);
+                return 1;
             }
             cur_node = next_node;
         }
@@ -1062,7 +1092,12 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                     tsk_getu32(fs->endian,
                     &node[nodesize - (rec + 1) * 4]);
                 if (rec_off > nodesize) {
-                    // @@@ ERROR
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_ext_find_extent_record_attr: offset of record %d in leaf node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off, nodesize);
+                    free(node);
+                    return 1;
                 }
                 key = (hfs_ext_key *) & node[rec_off];
 
@@ -1088,18 +1123,31 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
                 ext_off = tsk_getu32(fs->endian, key->start_block);
 
                 keylen = tsk_getu16(fs->endian, key->key_len);
-                // @@@ SANITY CHECK ON NODELEN AND rec_addr+2+keylen
+                if (rec_off+keylen > nodesize) {
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_ext_find_extent_record_attr: offset and keylenth of record %d in leaf node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off+keylen, nodesize);
+                    free(node);
+                    return 1;
+                }
 
+                // convert the extents to the TSK format
                 extents = (hfs_extents *) & node[rec_off + keylen];
-
                 attr_run =
                     hfs_extents_to_attr(fs, extents->extents, ext_off);
                 if (attr_run == NULL) {
-                    /// @@@
+                    strncat(tsk_errstr2, " - hfs_ext_find_extent_record_attr",
+                            TSK_ERRSTR_L - strlen(tsk_errstr2));
+                    free(node);
+                    return 1;
                 }
 
                 if (tsk_fs_attr_add_run(fs, a_attr, attr_run)) {
-                    // @@@
+                    strncat(tsk_errstr2, " - hfs_ext_find_extent_record_attr",
+                            TSK_ERRSTR_L - strlen(tsk_errstr2));
+                    free(node);
+                    return 1;
                 }
             }
         }
@@ -1107,7 +1155,7 @@ hfs_ext_find_extent_record_attr(HFS_INFO * hfs, uint32_t cnid,
             tsk_errno = TSK_ERR_FS_GENFS;
             snprintf(tsk_errstr, TSK_ERRSTR_L,
                 "hfs_ext_find_extent_record: btree node %" PRIu32
-                " (%" PRIu64 ") is neither index nor leaf (%" PRIu8 ")",
+                " (%" PRIuOFF ") is neither index nor leaf (%" PRIu8 ")",
                 cur_node, cur_off, node_desc->kind);
             free(node);
             return 1;
@@ -1165,11 +1213,9 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
 
     tsk_error_reset();
 
-
     nodesize = tsk_getu16(fs->endian, hfs->catalog_header.nodesize);
     if ((node = (char *) tsk_malloc(nodesize)) == NULL)
         return 0;
-    // @@@ ADD FREE CODE
 
     /* start at root node */
     cur_node = tsk_getu32(fs->endian, hfs->catalog_header.root);
@@ -1182,6 +1228,7 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
         if (tsk_verbose)
             tsk_fprintf(stderr, "hfs_cat_get_record_offset: "
                 "empty extents btree\n");
+        free(node);
         return 0;
     }
 
@@ -1202,7 +1249,13 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
         cnt = tsk_fs_attr_read(hfs->catalog_attr, cur_off,
             node, nodesize, 0);
         if (cnt != nodesize) {
-            // @@@
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_cat_get_record_offset: Error reading node %d at offset %"PRIuOFF, cur_node, cur_off);
+            free(node);
             return 0;
         }
 
@@ -1220,6 +1273,7 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
             snprintf(tsk_errstr, TSK_ERRSTR_L,
                 "hfs_cat_get_record_offset: zero records in node %"
                 PRIu32, cur_node);
+            free(node);
             return 0;
         }
 
@@ -1237,8 +1291,12 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                     tsk_getu16(fs->endian,
                     &node[nodesize - (rec + 1) * 2]);
                 if (rec_off > nodesize) {
-                    // @@@ ERROR
-                    return TSK_ERR;
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_cat_get_record_offset: offset of record %d in index node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off, nodesize);
+                    free(node);
+                    return 1;
                 }
                 key = (hfs_cat_key *) & node[rec_off];
 
@@ -1255,8 +1313,12 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                     || (next_node == 0)) {
                     int keylen = tsk_getu16(fs->endian, key->key_len) + 2;
                     if (rec_off + keylen > nodesize) {
-                        // @@@ ERROR
-                        return TSK_ERR;
+                        tsk_errno = TSK_ERR_FS_GENFS;
+                        snprintf(tsk_errstr, TSK_ERRSTR_L,
+                                 "hfs_cat_get_record_offset: offset of record and keylength %d in index node %d too large (%zu vs %"PRIu16")",
+                                 rec, cur_node, rec_off+keylen, nodesize);
+                        free(node);
+                        return 0;
                     }
                     next_node =
                         tsk_getu32(fs->endian, &node[rec_off + keylen]);
@@ -1265,8 +1327,12 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                     break;
                 }
             }
+            // check if we found any relevant node
             if (next_node == 0) {
-                // @@@@
+                tsk_errno = TSK_ERR_FS_GENFS;
+                snprintf(tsk_errstr, TSK_ERRSTR_L,
+                         "hfs_cat_get_record_offset: did not find any keys in index node %d",
+                         cur_node);
                 is_done = 1;
                 break;
             }
@@ -1287,7 +1353,11 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                     tsk_getu16(fs->endian,
                     &node[nodesize - (rec + 1) * 2]);
                 if (rec_off > nodesize) {
-                    // @@@ ERROR
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_cat_get_record_offset: offset of record %d in leaf node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off, nodesize);
+                    free(node);
                     return 0;
                 }
                 key = (hfs_cat_key *) & node[rec_off];
@@ -1315,7 +1385,11 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                 rec_off2 =
                     rec_off + 2 + tsk_getu16(fs->endian, key->key_len);
                 if (rec_off2 > nodesize) {
-                    // @@@ ERROR
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_cat_get_record_offset: offset of record and keylength %d in leaf node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off2, nodesize);
+                    free(node);
                     return 0;
                 }
 
@@ -1328,9 +1402,11 @@ hfs_cat_get_record_offset(HFS_INFO * hfs, hfs_cat_key * needle)
                 "hfs_cat_get_record_offset: btree node %" PRIu32
                 " (%" PRIu64 ") is neither index nor leaf (%" PRIu8 ")",
                 cur_node, cur_off, node_desc->kind);
+            free(node);
             return 0;
         }
     }
+    free(node);
     return 0;
 }
 
@@ -1356,7 +1432,12 @@ hfs_cat_read_thread_record(HFS_INFO * hfs, TSK_OFF_T off,
     memset(thread, 0, sizeof(hfs_thread));
     cnt = tsk_fs_attr_read(hfs->catalog_attr, off, (char *) thread, 10, 0);
     if (cnt != 10) {
-        // @@@
+        if (cnt >= 0) {
+            tsk_error_reset();
+            tsk_errno = TSK_ERR_FS_READ;
+        }
+        snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                 "hfs_cat_read_thread_record: Error reading catalog offset %"PRIuOFF" (header)", off);
         return 1;
     }
 
@@ -1384,7 +1465,12 @@ hfs_cat_read_thread_record(HFS_INFO * hfs, TSK_OFF_T off,
         tsk_fs_attr_read(hfs->catalog_attr, off + 10,
         (char *) thread->name.unicode, uni_len * 2, 0);
     if (cnt != uni_len * 2) {
-        // @@@
+        if (cnt >= 0) {
+            tsk_error_reset();
+            tsk_errno = TSK_ERR_FS_READ;
+        }
+        snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                 "hfs_cat_read_thread_record: Error reading catalog offset %"PRIuOFF" (name)", off+10);
         return 1;
     }
 
@@ -1409,7 +1495,12 @@ hfs_cat_read_file_folder_record(HFS_INFO * hfs, TSK_OFF_T off,
     memset(record, 0, sizeof(hfs_file_folder));
     cnt = tsk_fs_attr_read(hfs->catalog_attr, off, (char *) record, 2, 0);
     if (cnt != 2) {
-        // @@@
+        if (cnt >= 0) {
+            tsk_error_reset();
+            tsk_errno = TSK_ERR_FS_READ;
+        }
+        snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                 "hfs_cat_read_file_folder_record: Error reading catalog offset %"PRIuOFF" (header)", off);
         return 1;
     }
 
@@ -1418,7 +1509,12 @@ hfs_cat_read_file_folder_record(HFS_INFO * hfs, TSK_OFF_T off,
             tsk_fs_attr_read(hfs->catalog_attr, off, (char *) record,
             sizeof(hfs_folder), 0);
         if (cnt != sizeof(hfs_folder)) {
-            // @@@
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_cat_read_file_folder_record: Error reading catalog offset %"PRIuOFF" (folder)", off);
             return 1;
         }
     }
@@ -1428,7 +1524,12 @@ hfs_cat_read_file_folder_record(HFS_INFO * hfs, TSK_OFF_T off,
             tsk_fs_attr_read(hfs->catalog_attr, off, (char *) record,
             sizeof(hfs_file), 0);
         if (cnt != sizeof(hfs_file)) {
-            // @@@
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_cat_read_file_folder_record: Error reading catalog offset %"PRIuOFF" (file)", off);
             return 1;
         }
     }
@@ -1443,8 +1544,10 @@ hfs_cat_read_file_folder_record(HFS_INFO * hfs, TSK_OFF_T off,
     return 0;
 }
 
+
 /** \internal
- * Lookup an entry in the catalog file and save it into the entry
+ * Lookup an entry in the catalog file and save it into the entry.  Do not
+ * call this for the special files that do not have an entry in the catalog. 
  * data structure.
  * @param hfs File system being analyzed
  * @param inum Address (cnid) of file to open
@@ -1473,7 +1576,9 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
         (inum == HFS_ALLOCATION_FILE_ID) ||
         (inum == HFS_STARTUP_FILE_ID) ||
         (inum == HFS_ATTRIBUTES_FILE_ID)) {
-        // @@@ Add error message
+        tsk_errno = TSK_ERR_FS_GENFS;
+        snprintf(tsk_errstr, TSK_ERRSTR_L,
+                 "hfs_cat_file_lookup: Called on special file: %"PRIuINUM, inum);
         return 1;
     }
 
@@ -1485,13 +1590,16 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
 
     /* look up the thread record */
     off = hfs_cat_get_record_offset(hfs, &key);
-
-    if (off == 0)
+    if (off == 0) {
+        snprintf(tsk_errstr2, TSK_ERRSTR_L, " hfs_cat_file_lookup: thread for file (%"PRIuINUM")", inum);
         return 1;
+    }
 
     /* read the thread record */
-    if (hfs_cat_read_thread_record(hfs, off, &thread))
+    if (hfs_cat_read_thread_record(hfs, off, &thread)) {
+        snprintf(tsk_errstr2, TSK_ERRSTR_L, " hfs_cat_file_lookup: file (%"PRIuINUM")", inum);
         return 1;
+    }
 
     /* now look up the actual file/folder record */
 
@@ -1503,12 +1611,16 @@ hfs_cat_file_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry)
 
     /* look up the record */
     off = hfs_cat_get_record_offset(hfs, &key);
-    if (off == 0)
+    if (off == 0) {
+        snprintf(tsk_errstr2, TSK_ERRSTR_L, " hfs_cat_file_lookup: file (%"PRIuINUM")", inum);
         return 1;
+    }
 
     /* read the record */
-    if (hfs_cat_read_file_folder_record(hfs, off, &record))
+    if (hfs_cat_read_file_folder_record(hfs, off, &record)) {
+        snprintf(tsk_errstr2, TSK_ERRSTR_L, " hfs_cat_file_lookup: file (%"PRIuINUM")", inum);
         return 1;
+    }
 
     /* these memcpy can be gotten rid of, really */
     if (tsk_getu16(fs->endian, record.file.rec_type) == HFS_FOLDER_RECORD) {
@@ -2030,9 +2142,9 @@ hfs_dinode_copy(HFS_INFO * a_hfs, const hfs_file * a_entry,
     }
 
     a_fs_meta->mode =
-        hfsmode2tskmode(tsk_getu32(fs->endian, a_entry->perm.mode));
+        hfsmode2tskmode(tsk_getu16(fs->endian, a_entry->perm.mode));
     a_fs_meta->type =
-        hfsmode2tskmetatype(tsk_getu32(fs->endian, a_entry->perm.mode));
+        hfsmode2tskmetatype(tsk_getu16(fs->endian, a_entry->perm.mode));
 
     if (tsk_getu16(fs->endian, a_entry->rec_type) == HFS_FOLDER_RECORD) {
         a_fs_meta->size = 0;
@@ -2216,12 +2328,6 @@ hfs_load_attrs(TSK_FS_FILE * fs_file)
         fs_file->meta->attr = tsk_fs_attrlist_alloc();
     }
 
-
-    //@@@ is this teh best response?
-    // need to come up with compete plan on dealig with directories, size, content etc. 
-    if (fs_file->meta->type != TSK_FS_META_TYPE_REG)
-        return 0;
-
     // get an attribute structure to store the data in
     if ((fs_attr =
             tsk_fs_attrlist_getnew(fs_file->meta->attr,
@@ -2230,6 +2336,21 @@ hfs_load_attrs(TSK_FS_FILE * fs_file)
             TSK_ERRSTR_L - strlen(tsk_errstr2));
         return 1;
     }
+    
+    // if not a file, then make an empty entry
+    if (fs_file->meta->type != TSK_FS_META_TYPE_REG) {
+        if (tsk_fs_attr_set_run(fs_file, fs_attr, NULL, NULL,
+                                TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,
+                                0, 0, 0, 0)) {
+            strncat(tsk_errstr2, " - hfs_load_attrs (non-file)",
+                    TSK_ERRSTR_L - strlen(tsk_errstr2));
+            tsk_fs_attr_free(fs_attr);
+            tsk_fs_attr_run_free(attr_run);
+            return 1;
+        }
+        fs_file->meta->attr_state = TSK_FS_META_ATTR_STUDIED;
+        return 0;
+    }
 
     // Get the data fork and convert it to the TSK format
     fork = (hfs_fork *) fs_file->meta->content_ptr;
@@ -2261,7 +2382,7 @@ hfs_load_attrs(TSK_FS_FILE * fs_file)
         return 1;
     }
 
-    // @@@ Resource fork too
+    // @@@ Load resource fork too
 
     fs_file->meta->attr_state = TSK_FS_META_ATTR_STUDIED;
 
@@ -2284,8 +2405,8 @@ static int8_t
 hfs_block_is_alloc(HFS_INFO * hfs, TSK_DADDR_T a_addr)
 {
     TSK_FS_INFO *fs = &(hfs->fs_info);
-    int b;
-    int b2;
+    TSK_OFF_T b;
+    size_t b2;
 
     // lazy loading
     if (hfs->blockmap_file == NULL) {
@@ -2311,7 +2432,7 @@ hfs_block_is_alloc(HFS_INFO * hfs, TSK_DADDR_T a_addr)
     }
 
     // get the byte offset
-    b = (int) a_addr / 8;
+    b = (TSK_OFF_T) a_addr / 8;
     if (b > hfs->blockmap_file->meta->size) {
         tsk_errno = TSK_ERR_FS_CORRUPT;
         snprintf(tsk_errstr, TSK_ERRSTR_L,
@@ -2329,7 +2450,12 @@ hfs_block_is_alloc(HFS_INFO * hfs, TSK_DADDR_T a_addr)
             hfs->blockmap_cache,
             sizeof(hfs->blockmap_cache), 0);
         if (cnt != sizeof(hfs->blockmap_cache)) {
-            // @@@
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_block_is_alloc: Error reading block bitmap at offset %"PRIuOFF, b);            
             return -1;
         }
         hfs->blockmap_cache_start = b;
@@ -3107,7 +3233,12 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
         (char *) &(hfs->catalog_header),
         sizeof(hfs_btree_header_record), 0);
     if (cnt != sizeof(hfs_btree_header_record)) {
-        // @@@
+        if (cnt >= 0) {
+            tsk_error_reset();
+            tsk_errno = TSK_ERR_FS_READ;
+        }
+        snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                 "hfs_open: Error reading catalog header");           
         fs->tag = 0;
         free(hfs->fs);
         free(hfs);
@@ -3135,11 +3266,9 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
         hfs->is_case_sensitive = 0;
     }
 
-    // @@@@ inum_count should be last-first
     // update the numbers.
     fs->last_inum = hfs_find_highest_inum(hfs);
-    fs->inum_count = tsk_getu32(fs->endian, hfs->fs->file_cnt) +
-        tsk_getu32(fs->endian, hfs->fs->fldr_cnt);
+    fs->inum_count = fs->last_inum+1;
 
     snprintf((char *) fs->fs_id, 17, "%08" PRIx32 "%08" PRIx32,
         tsk_getu32(fs->endian, &(hfs->fs->finder_info[24])),
diff --git a/tsk3/fs/hfs_dent.c b/tsk3/fs/hfs_dent.c
index 9fc569831d363fde780b0dd3b936589b5db00603..c40d8eaa61360816072e20241f7c701558d0840f 100644
--- a/tsk3/fs/hfs_dent.c
+++ b/tsk3/fs/hfs_dent.c
@@ -254,7 +254,7 @@ hfs_dir_open_meta3(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
     memset((char *) &needle, 0, sizeof(hfs_cat_key));
 
     temp_32ptr = (uint32_t *) (needle.parent_cnid);
-    *temp_32ptr = tsk_getu32(fs->endian, (char *) &cnid);       // @@@@ I'm not sure that this works...
+    *temp_32ptr = tsk_getu32(fs->endian, (char *) &cnid);       //  I'm not sure that this works...
 
     /*** navigate to thread record ***/
 
@@ -282,8 +282,6 @@ hfs_dir_open_meta3(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
             "root node %" PRIu32 "; header @ %" PRIu64 "; leafsize = %"
             PRIu16 "\n", cur_node, off, leafsize);
 
-    // @@@ We can probably merge this content with tree code in hfs.c.
-    // @@@ Change names from addr to off
     while (1) {
         uint16_t rec, recno;
         TSK_OFF_T recoff;
@@ -449,7 +447,6 @@ hfs_dir_open_meta3(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                 if (a_addr == fs->root_inum)
                     fs_name->meta_addr = fs->root_inum;
                 else
-					// @@@ VS warns that entry is uninitialized...debug
                     fs_name->meta_addr =
                         tsk_getu32(fs->endian, entry.thread.parent_cnid);
 
@@ -616,15 +613,16 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
          tsk_fs_file_open_meta(fs, NULL, a_addr)) == NULL) {
         strncat(tsk_errstr2, " - hfs_dir_open_meta",
                 TSK_ERRSTR_L - strlen(tsk_errstr2));
-        tsk_fs_dir_close(fs_dir);
+        tsk_fs_name_free(fs_name);
         return TSK_ERR;
     }
     
     
     nodesize = tsk_getu16(fs->endian, hfs->catalog_header.nodesize);
-    if ((node = (char *) tsk_malloc(nodesize)) == NULL)
-        return 1;
-    // @@@ ADD FREE CODE
+    if ((node = (char *) tsk_malloc(nodesize)) == NULL) {
+        tsk_fs_name_free(fs_name);
+        return TSK_ERR;
+    }
     
     /* start at root node */
     cur_node = tsk_getu32(fs->endian, hfs->catalog_header.root);
@@ -637,7 +635,9 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
         if (tsk_verbose)
             tsk_fprintf(stderr, "hfs_dir_open_meta: "
                         "empty extents btree\n");
-        return 0;
+        tsk_fs_name_free(fs_name);
+        free(node);
+        return TSK_OK;
     }
     
     if (tsk_verbose)
@@ -657,8 +657,15 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
         cnt = tsk_fs_attr_read(hfs->catalog_attr, cur_off,
                                node, nodesize, 0);
         if (cnt != nodesize) {
-            // @@@
-            return 1;
+            if (cnt >= 0) {
+                tsk_error_reset();
+                tsk_errno = TSK_ERR_FS_READ;
+            }
+            snprintf(tsk_errstr2, TSK_ERRSTR_L,
+                     "hfs_dir_open_meta: Error reading catalog node %d at offset %"PRIuOFF, cur_node, cur_off); 
+            tsk_fs_name_free(fs_name);
+            free(node);
+            return TSK_ERR;
         }
         
         node_desc = (hfs_btree_node *) node;
@@ -675,7 +682,9 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
             snprintf(tsk_errstr, TSK_ERRSTR_L,
                      "hfs_dir_open_meta: zero records in node %"
                      PRIu32, cur_node);
-            return 1;
+            tsk_fs_name_free(fs_name);
+            free(node);
+            return TSK_COR;
         }
         
         
@@ -693,8 +702,13 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     tsk_getu16(fs->endian,
                                &node[nodesize - (rec + 1) * 2]);
                 if (rec_off > nodesize) {
-                    // @@@ ERROR
-                    return TSK_ERR;
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_dir_open_meta: offset of record %d in index node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off, nodesize);
+                    tsk_fs_name_free(fs_name);
+                    free(node);
+                    return TSK_COR;
                 }
                 key = (hfs_cat_key *) & node[rec_off];
                 
@@ -710,8 +724,13 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                 if ((tsk_getu32(fs->endian, key->parent_cnid) <= cnid) || (next_node == 0)) {
                     int keylen = tsk_getu16(fs->endian, key->key_len) + 2;
                     if (rec_off + keylen > nodesize) {
-                        // @@@ ERROR
-                        return TSK_ERR;
+                        tsk_errno = TSK_ERR_FS_GENFS;
+                        snprintf(tsk_errstr, TSK_ERRSTR_L,
+                                 "hfs_dir_open_meta: offset of record + keylen %d in index node %d too large (%zu vs %"PRIu16")",
+                                 rec, cur_node, rec_off+keylen, nodesize);
+                        tsk_fs_name_free(fs_name);
+                        free(node);
+                        return TSK_COR;
                     }
                     next_node =
                         tsk_getu32(fs->endian, &node[rec_off + keylen]);
@@ -721,7 +740,10 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                 }
             }
             if (next_node == 0) {
-                // @@@@
+                tsk_errno = TSK_ERR_FS_GENFS;
+                snprintf(tsk_errstr, TSK_ERRSTR_L,
+                         "hfs_dir_open_meta: did not find any keys for %d in index node %d",
+                         cnid, cur_node);
                 is_done = 1;
                 break;
             }
@@ -742,8 +764,13 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     tsk_getu16(fs->endian,
                                &node[nodesize - (rec + 1) * 2]);
                 if (rec_off > nodesize) {
-                    // @@@ ERROR
-                    return TSK_ERR;
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_dir_open_meta: offset of record %d in leaf node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off, nodesize);
+                    tsk_fs_name_free(fs_name);
+                    free(node);
+                    return TSK_COR;
                 }
                 key = (hfs_cat_key *) & node[rec_off];
                 
@@ -754,8 +781,6 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                                 tsk_getu16(fs->endian, key->key_len),
                                 tsk_getu32(fs->endian, key->parent_cnid));
                 
-//                rec_cnid = tsk_getu32(fs->endian, key->file_id);
-                
                 // see if this record is for our file or if we passed the interesting entries
                 if (tsk_getu32(fs->endian, key->parent_cnid) < cnid) {
                     continue;
@@ -765,17 +790,25 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     break;
                 }
                
-                
-//                HERE
                 rec_off2 = rec_off + 2 + tsk_getu16(fs->endian, key->key_len);
                 if (rec_off2 > nodesize) {
-                    // @@@ ERROR
-                    return TSK_ERR;
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_dir_open_meta: offset of record+keylen %d in leaf node %d too large (%zu vs %"PRIu16")",
+                             rec, cur_node, rec_off2, nodesize);
+                    tsk_fs_name_free(fs_name);
+                    free(node);
+                    return TSK_COR;
                 }
-                // @@@ Add length checks...
                 rec_type = tsk_getu16(fs->endian, &node[rec_off2]);
                 if (rec_type == HFS_FILE_THREAD) {
-                    // we shouldn't get this
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_dir_open_meta: Got File Thread record in record %d in leaf node %d",
+                             rec, cur_node);
+                    tsk_fs_name_free(fs_name);
+                    free(node);
+                    return TSK_COR;
                 }
                 
                 /* This will link the folder to its parent, which is the ".." entry */
@@ -798,8 +831,11 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     
                     if (hfs_uni2ascii(fs, key->name.unicode,
                                       tsk_getu16(fs->endian, key->name.length),
-                                      fs_name->name, HFS_MAXNAMLEN + 1))
-                        return 1;
+                                      fs_name->name, HFS_MAXNAMLEN + 1)) {
+                        tsk_fs_name_free(fs_name);
+                        free(node);
+                        return TSK_ERR;
+                    }
                 }
                 
                 /* This is a normal file in the folder */
@@ -811,16 +847,25 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                     fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;                     
                     if (hfs_uni2ascii(fs, key->name.unicode,
                                       tsk_getu16(fs->endian, key->name.length),
-                                      fs_name->name, HFS_MAXNAMLEN + 1))
-                        return 1;
+                                      fs_name->name, HFS_MAXNAMLEN + 1)) {
+                        tsk_fs_name_free(fs_name);
+                        free(node);
+                        return TSK_ERR;
+                    }
                 }
                 else {
-                    return 1;
-                    // @@@
+                    tsk_errno = TSK_ERR_FS_GENFS;
+                    snprintf(tsk_errstr, TSK_ERRSTR_L,
+                             "hfs_dir_open_meta: Unknown record type %d in leaf node %d",
+                             rec_type, cur_node);
+                    tsk_fs_name_free(fs_name);
+                    free(node);
+                    return TSK_COR;                    
                 }
                 
                 if (tsk_fs_dir_add(fs_dir, fs_name)) {
                     tsk_fs_name_free(fs_name);
+                    free(node);
                     return TSK_ERR;
                 }                
             }
@@ -831,9 +876,14 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
                      "hfs_dir_open_meta: btree node %" PRIu32
                      " (%" PRIu64 ") is neither index nor leaf (%" PRIu8 ")",
                      cur_node, cur_off, node_desc->kind);
-            return 1;
+            
+            tsk_fs_name_free(fs_name);
+            free(node);
+            return TSK_COR;
         }
     }
-    return 0;
+    tsk_fs_name_free(fs_name);
+    free(node);
+    return TSK_OK;
 }
 
diff --git a/tsk3/fs/ntfs_dent.c b/tsk3/fs/ntfs_dent.c
index 62732275e6e91f51c6c24c12b3ccb7d6ef794ed5..ae18fa477bbd92b09adb20be4ba55f9280e2dd18 100644
--- a/tsk3/fs/ntfs_dent.c
+++ b/tsk3/fs/ntfs_dent.c
@@ -546,7 +546,6 @@ ntfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
             tsk_fs_file_open_meta(a_fs, NULL, a_addr)) == NULL) {
         strncat(tsk_errstr2, " - ntfs_dir_open_meta",
             TSK_ERRSTR_L - strlen(tsk_errstr2));
-        tsk_fs_dir_close(fs_dir);
         return TSK_COR;
     }