📄 hfs_dent.c
字号:
if (tsk_verbose >= 2) tsk_fprintf(stderr, "hfs_dir_open_meta: starting at " "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; /* load node header */ cur_off = hfs_cat_find_node_offset(hfs, cur_node); if (cur_off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: find catalog node %" PRIu32, cur_node); return 1; } if (hfs_checked_read_random(fs, (char *) &node, sizeof(node), cur_off)) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: read catalog node %" PRIu32 " at %" PRIuDADDR, cur_node, cur_off); return 1; } num_rec = tsk_getu16(fs->endian, node.num_rec); if (tsk_verbose >= 2) tsk_fprintf(stderr, "hfs_dir_open_meta: node %" PRIu32 " @ %" PRIu64 " has %" PRIu16 " records\n", cur_node, cur_off, num_rec); if (num_rec == 0) { /* big problem */ tsk_errno = TSK_ERR_FS_GENFS; snprintf(tsk_errstr, TSK_ERRSTR_L, "hfs_dir_open_meta: zero records in node %" PRIu32, cur_node); return 1; } /* find largest key smaller than or equal to our key */ recno = 0; recoff = 0; for (rec = 0; rec < num_rec; rec++) { int cmp; off = hfs_get_bt_rec_off(hfs, cur_off, leafsize, rec); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: finding record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 1; } off = hfs_read_key(hfs, &header, off, (char *) &key, sizeof(hfs_cat_key), 1); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: reading record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 0; } cmp = hfs_compare_catalog_keys(hfs, &key, &needle); if (tsk_verbose >= 2) tsk_fprintf(stderr, "hfs_dir_open_meta: record %" PRIu16 " @ %" PRIu64 "; keylen %" PRIu16 " (%" PRIu32 ", %" PRIu16 "); compare: %d\n", rec, off, tsk_getu16(fs->endian, key.key_len), tsk_getu32(fs->endian, key.parent_cnid), tsk_getu16(fs->endian, key.name.length), cmp); /* find the largest key less than or equal to our key */ /* if all keys are larger than our key, select the leftmost key */ if ((cmp <= 0) || (recoff == 0)) { recoff = off; recno = rec; } if (cmp >= 0) break; } if (node.kind == HFS_BTREE_INDEX_NODE) { /* replace cur node number with the node number referenced * by the found key, continue */ if (hfs_checked_read_random(fs, buf, 4, recoff)) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: reading pointer in record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 1; } cur_node = tsk_getu32(fs->endian, buf); } else if (node.kind == HFS_BTREE_LEAF_NODE) { rec = recno; /* using rec as our counting variable again, for kicks */ /* reget key */ off = hfs_get_bt_rec_off(hfs, cur_off, leafsize, rec); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: finding record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 1; } off = hfs_read_key(hfs, &header, off, (char *) &key, sizeof(hfs_ext_key), 1); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_find_catalog_record: reading record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 1; } if (hfs_compare_catalog_keys(hfs, &key, &needle) == 0) { /*** thread record found ***/ /* read the thread record */ if (hfs_read_thread_record(hfs, off, &thread)) return 1; /* see that it is really a thread record */ if (tsk_getu16(fs->endian, thread.record_type) == HFS_FOLDER_THREAD) { if (tsk_verbose) fprintf(stderr, "hfs_dir_open_meta: found folder thread record for %" PRIu32 "\n", cnid); } else if (tsk_getu16(fs->endian, thread.record_type) == HFS_FILE_THREAD) { if (tsk_verbose) fprintf(stderr, "hfs_dir_open_meta: found file thread record for %" PRIu32 "\n", cnid); return 0; /* here, it's decided that traversing a directory that's actually a file * is not an error, but produces a zero traversal */ /* theoretically a file could have children, if you modified the hfs+ structure on disk manually */ } if (tsk_verbose) fprintf(stderr, "hfs_dir_open_meta: parent cnid %" PRIu32 "\n", tsk_getu32(fs->endian, thread.parent_cnid)); /* * "." */ fs_name->meta_addr = a_addr; strcpy(fs_name->name, "."); fs_name->type = TSK_FS_NAME_TYPE_DIR; fs_name->flags = TSK_FS_NAME_FLAG_ALLOC; if (tsk_fs_dir_add(fs_dir, fs_name)) { tsk_fs_name_free(fs_name); return TSK_ERR; } /* * ".." */ /* the parent of root is 1, but there is no inode 1 */ /* well, there is, but you don't want it */ 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); strcpy(fs_name->name, ".."); fs_name->type = TSK_FS_NAME_TYPE_DIR; fs_name->flags = TSK_FS_NAME_FLAG_ALLOC; if (tsk_fs_dir_add(fs_dir, fs_name)) { tsk_fs_name_free(fs_name); return TSK_ERR; } /*** iterate over all folder children ***/ while (1) { /* go to the next record */ if (!hfs_cat_next_record(hfs, &rec, &num_rec, &node, &cur_node, &cur_off, &header)) { /* here, means that we are done (also that our file is the at end of the tree, neat) */ tsk_fs_name_free(fs_name); if (tsk_errno != 0) return 1; if (tsk_verbose) tsk_fprintf(stderr, "hfs_dir_open_meta: " "end of catalog btree reached while traversing children\n"); return 0; } /* load new key data, since I'm about to use it */ off = hfs_get_bt_rec_off(hfs, cur_off, leafsize, rec); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_dir_open_meta: finding record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 1; } off = hfs_read_key(hfs, &header, off, (char *) &key, sizeof(hfs_cat_key), 1); if (off == 0) { snprintf(tsk_errstr2, TSK_ERRSTR_L, "hfs_find_catalog_record: reading record %" PRIu16 " in node %" PRIu32, rec, cur_node); return 1; } if (tsk_getu32(fs->endian, key.parent_cnid) != cnid) { /* traversed into the land of not-our-children */ tsk_fs_name_free(fs_name); return 0; } /* read the record */ if (hfs_read_file_folder_record(hfs, off, (hfs_file_folder *) & entry.cat)) return 1; if (hfs_uni2ascii(fs, key.name.unicode, tsk_getu16(fs->endian, key.name.length), fs_name->name, HFS_MAXNAMLEN + 1)) return 1; entry.inum = tsk_getu32(fs->endian, entry.cat.cnid); fs_name->meta_addr = tsk_getu32(fs->endian, entry.cat.cnid); fs_name->type = hfsmode2tsknametype(tsk_getu16(fs->endian, entry.cat.perm.mode)); if ((fs_name->type == TSK_FS_NAME_TYPE_DIR) != (tsk_getu16(fs->endian, entry.cat.rec_type) == HFS_FOLDER_RECORD)) { tsk_fprintf(stderr, "ERROR: disagreement on whether a file is a directory: %" PRIu16 " vs %" PRIu16 "\n", fs_name->type, tsk_getu16(fs->endian, entry.cat.rec_type)); } fs_name->flags = TSK_FS_NAME_FLAG_ALLOC; if (tsk_fs_dir_add(fs_dir, fs_name)) { tsk_fs_name_free(fs_name); return TSK_ERR; } } } return 0; /* this key not found */ } else { tsk_errno = TSK_ERR_FS_GENFS; snprintf(tsk_errstr, TSK_ERRSTR_L, "hfs_dir_open_meta: btree node %" PRIu32 " (%" PRIu64 ") is neither index nor leaf (%" PRIu8 ")", cur_node, cur_off, node.kind); return 1; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -