/** \ingroup fslib * Return a specific type and id attribute for the file. * @param a_fs_file File to get data from * @param a_type Type of attribute to load * @param a_id Id of attribute to load * @param a_id_used Set to 1 if ID is actually set or 0 to use default * @returns NULL on error */ const TSK_FS_ATTR * tsk_fs_file_attr_get_type(TSK_FS_FILE * a_fs_file, TSK_FS_ATTR_TYPE_ENUM a_type, uint16_t a_id, uint8_t a_id_used) { if (tsk_fs_file_attr_check(a_fs_file, "tsk_fs_file_attr_get_type")) return NULL; if (a_id_used) return tsk_fs_attrlist_get_id(a_fs_file->meta->attr, a_type, a_id); else return tsk_fs_attrlist_get(a_fs_file->meta->attr, a_type); }
uint8_t ntfs_find_file(TSK_FS_INFO * fs, TSK_INUM_T inode_toid, uint32_t type_toid, uint8_t type_used, uint16_t id_toid, uint8_t id_used, TSK_FS_DIR_WALK_FLAG_ENUM dir_walk_flags, TSK_FS_DIR_WALK_CB action, void *ptr) { TSK_FS_META_NAME_LIST *fs_name_list; NTFS_INFO *ntfs = (NTFS_INFO *) fs; char *attr = NULL; NTFS_DINFO dinfo; TSK_FS_FILE *fs_file; /* sanity check */ if (inode_toid < fs->first_inum || inode_toid > fs->last_inum) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ntfs_find_file: invalid inode value: %" PRIuINUM "\n", inode_toid); return 1; } // open the file to ID fs_file = tsk_fs_file_open_meta(fs, NULL, inode_toid); if (fs_file == NULL) { strncat(tsk_errstr2, " - ntfs_find_file", TSK_ERRSTR_L - strlen(tsk_errstr2)); tsk_fs_file_close(fs_file); return 1; } // see if its allocation status meets the callback needs if ((fs_file->meta->flags & TSK_FS_META_FLAG_ALLOC) && ((dir_walk_flags & TSK_FS_DIR_WALK_FLAG_ALLOC) == 0)) { tsk_fs_file_close(fs_file); return 1; } else if ((fs_file->meta->flags & TSK_FS_META_FLAG_UNALLOC) && ((dir_walk_flags & TSK_FS_DIR_WALK_FLAG_UNALLOC) == 0)) { tsk_fs_file_close(fs_file); return 1; } /* Allocate a name and fill in some details */ if ((fs_file->name = tsk_fs_name_alloc(NTFS_MAXNAMLEN_UTF8, 0)) == NULL) { return 1; } fs_file->name->meta_addr = inode_toid; fs_file->name->meta_seq = 0; fs_file->name->flags = ((tsk_getu16(fs->endian, ntfs-> mft->flags) & NTFS_MFT_INUSE) ? TSK_FS_NAME_FLAG_ALLOC : TSK_FS_NAME_FLAG_UNALLOC); memset(&dinfo, 0, sizeof(NTFS_DINFO)); /* in this function, we use the dinfo->dirs array in the opposite order. * we set the end of it to NULL and then prepend the * directories to it * * dinfo->didx[dinfo->depth] will point to where the current level started their * dir name */ dinfo.dirs[DIR_STRSZ - 2] = '/'; dinfo.dirs[DIR_STRSZ - 1] = '\0'; dinfo.didx[0] = &dinfo.dirs[DIR_STRSZ - 2]; dinfo.depth = 1; /* Get the name for the attribute - if specified */ if (type_used) { const TSK_FS_ATTR *fs_attr; if (id_used) fs_attr = tsk_fs_attrlist_get_id(fs_file->meta->attr, type_toid, id_toid); else fs_attr = tsk_fs_attrlist_get(fs_file->meta->attr, type_toid); if (!fs_attr) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_INODE_COR; snprintf(tsk_errstr, TSK_ERRSTR_L, "find_file: Type %" PRIu32 " Id %" PRIu16 " not found in MFT %" PRIuINUM "", type_toid, id_toid, inode_toid); tsk_fs_file_close(fs_file); return 1; } /* only add the attribute name if it is the non-default data stream */ if (strcmp(fs_attr->name, "$Data") != 0) attr = fs_attr->name; } /* loop through all the names it may have */ for (fs_name_list = fs_file->meta->name2; fs_name_list != NULL; fs_name_list = fs_name_list->next) { int retval; /* Append on the attribute name, if it exists */ if (attr != NULL) { snprintf(fs_file->name->name, fs_file->name->name_size, "%s:%s", fs_name_list->name, attr); } else { strncpy(fs_file->name->name, fs_name_list->name, fs_file->name->name_size); } /* if this is in the root directory, then call back */ if (fs_name_list->par_inode == NTFS_ROOTINO) { retval = action(fs_file, dinfo.didx[0], ptr); if (retval == TSK_WALK_STOP) { tsk_fs_file_close(fs_file); return 0; } else if (retval == TSK_WALK_ERROR) { tsk_fs_file_close(fs_file); return 1; } } /* call the recursive function on the parent to get the full path */ else { if (ntfs_find_file_rec(fs, &dinfo, fs_file, fs_name_list, action, ptr)) { tsk_fs_file_close(fs_file); return 1; } } } /* end of name loop */ tsk_fs_file_close(fs_file); return 0; }