📄 fatfs_meta.c
字号:
dep = (fatfs_dentry *) & fatfs->dinodes[sidx << fatfs->ssize_sh]; /* if we know it is not part of a directory and it is not valid dentires, * then skip it */ if ((isset(sect_alloc, sect) == 0) && (fatfs_isdentry(fatfs, dep) == 0)) { sect++; continue; } /* See if the last inode in this sector is smaller than the starting one */ if (FATFS_SECT_2_INODE(fatfs, sect + 1) < start_inum) { sect++; continue; } /* get the base inode address of this sector */ inum = FATFS_SECT_2_INODE(fatfs, sect); if (tsk_verbose) tsk_fprintf(stderr, "fatfs_inode_walk: Processing sector %" PRIuDADDR " starting at inode %" PRIuINUM "\n", sect, inum); /* cycle through the directory entries */ for (didx = 0; didx < fatfs->dentry_cnt_se; didx++, inum++, dep++) { int retval; TSK_RETVAL_ENUM retval2; /* If less, then move on */ if (inum < start_inum) continue; /* If we are done, then exit from the loops */ if (inum > end_inum_tmp) { done = 1; break; } /* if this is a long file name entry, then skip it and * wait for the short name */ if ((dep->attrib & FATFS_ATTR_LFN) == FATFS_ATTR_LFN) continue; /* we don't care about . and .. entries because they * are redundant of other 'inode' entries */ if (((dep->attrib & FATFS_ATTR_DIRECTORY) == FATFS_ATTR_DIRECTORY) && (dep->name[0] == '.')) continue; /* Allocation status * This is determined first by the sector allocation status * an then the dentry flag. When a directory is deleted, the * contents are not always set to unallocated */ if (clustalloc == 1) { myflags = ((dep->name[0] == FATFS_SLOT_DELETED) ? TSK_FS_META_FLAG_UNALLOC : TSK_FS_META_FLAG_ALLOC); } else { myflags = TSK_FS_META_FLAG_UNALLOC; } if ((a_flags & myflags) != myflags) continue; /* Slot has not been used yet */ myflags |= ((dep->name[0] == FATFS_SLOT_EMPTY) ? TSK_FS_META_FLAG_UNUSED : TSK_FS_META_FLAG_USED); if ((a_flags & myflags) != myflags) continue; /* If we want only orphans, then check if this * inode is in the seen list */ if ((myflags & TSK_FS_META_FLAG_UNALLOC) && (a_flags & TSK_FS_META_FLAG_ORPHAN) && (tsk_list_find(fs->list_inum_named, inum))) { continue; } /* Do a final sanity check */ if (0 == fatfs_isdentry(fatfs, dep)) continue; if ((retval2 = fatfs_dinode_copy(fatfs, fs_file->meta, dep, sect, inum)) != TSK_OK) { /* Ignore this error and continue */ if (retval2 == TSK_COR) { if (tsk_verbose) tsk_error_print(stderr); tsk_error_reset(); continue; } else { tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } } if (tsk_verbose) tsk_fprintf(stderr, "fatfs_inode_walk: Directory Entry %" PRIuINUM " (%u) at sector %" PRIuDADDR "\n", inum, didx, sect); retval = a_action(fs_file, a_ptr); if (retval == TSK_WALK_STOP) { tsk_fs_file_close(fs_file); free(sect_alloc); return 0; } else if (retval == TSK_WALK_ERROR) { tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } } /* dentries */ sect++; if (done) break; } if (done) break; } free(sect_alloc); // handle the virtual orphans folder and FAT files if they asked for them if ((end_inum > fs->last_inum - FATFS_NUM_SPECFILE) && (a_flags & TSK_FS_META_FLAG_ALLOC) && (a_flags & TSK_FS_META_FLAG_USED) && ((a_flags & TSK_FS_META_FLAG_ORPHAN) == 0)) { TSK_INUM_T inum; // cycle through the special files for (inum = fs->last_inum - FATFS_NUM_SPECFILE + 1; inum <= end_inum; inum++) { int retval; if (inum == FATFS_MBRINO(fs)) { if (fatfs_make_mbr(fatfs, fs_file->meta)) { tsk_fs_file_close(fs_file); return 1; } } else if (inum == FATFS_FAT1INO(fs)) { if (fatfs_make_fat(fatfs, 1, fs_file->meta)) { tsk_fs_file_close(fs_file); return 1; } } else if (inum == FATFS_FAT2INO(fs)) { if (fatfs_make_fat(fatfs, 2, fs_file->meta)) { tsk_fs_file_close(fs_file); return 1; } } else if (inum == TSK_FS_ORPHANDIR_INUM(fs)) { if (tsk_fs_dir_make_orphan_dir_meta(fs, fs_file->meta)) { tsk_fs_file_close(fs_file); return 1; } } retval = a_action(fs_file, a_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; } } } tsk_fs_file_close(fs_file); return 0;} /* end of inode_walk *//* * return the contents of a specific inode * * 1 is returned if an error occurs or if the entry is not * a valid inode */uint8_tfatfs_inode_lookup(TSK_FS_INFO * fs, TSK_FS_FILE * a_fs_file, TSK_INUM_T inum){ FATFS_INFO *fatfs = (FATFS_INFO *) fs; ssize_t cnt; TSK_DADDR_T sect; size_t off; TSK_RETVAL_ENUM retval; // clean up any error messages that are lying around tsk_error_reset(); /* * Sanity check. */ if (inum < fs->first_inum || inum > fs->last_inum) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_INODE_NUM; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_inode_lookup: %" PRIuINUM " too large/small", inum); return 1; } if (a_fs_file == NULL) { tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_inode_lookup: fs_file is NULL"); return 1; } if (a_fs_file->meta == NULL) { if ((a_fs_file->meta = tsk_fs_meta_alloc(FATFS_FILE_CONTENT_LEN)) == NULL) return 1; } else { tsk_fs_meta_reset(a_fs_file->meta); } /* As there is no real root inode in FAT, use the made up one */ if (inum == FATFS_ROOTINO) { fatfs->dep = NULL; if (fatfs_make_root(fatfs, a_fs_file->meta)) return 1; else return 0; } else if (inum == FATFS_MBRINO(fs)) { fatfs->dep = NULL; if (fatfs_make_mbr(fatfs, a_fs_file->meta)) return 1; else return 0; } else if (inum == FATFS_FAT1INO(fs)) { fatfs->dep = NULL; if (fatfs_make_fat(fatfs, 1, a_fs_file->meta)) return 1; else return 0; } else if (inum == FATFS_FAT2INO(fs)) { fatfs->dep = NULL; if (fatfs_make_fat(fatfs, 2, a_fs_file->meta)) return 1; else return 0; } else if (inum == TSK_FS_ORPHANDIR_INUM(fs)) { fatfs->dep = NULL; if (tsk_fs_dir_make_orphan_dir_meta(fs, a_fs_file->meta)) return 1; else return 0; } /* Get the sector that this inode would be in and its offset */ sect = FATFS_INODE_2_SECT(fatfs, inum); off = FATFS_INODE_2_OFF(fatfs, inum); if (sect > fs->last_block) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_INODE_NUM; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_inode_lookup: Inode %" PRIuINUM " in sector too big for image: %" PRIuDADDR, inum, sect); return 1; } if (tsk_verbose) tsk_fprintf(stderr, "fatfs_inode_lookup: reading sector %" PRIuDADDR " for inode %" PRIuINUM "\n", sect, inum); cnt = tsk_fs_read_block(fs, sect, fatfs->dinodes, fatfs->ssize); if (cnt != fatfs->ssize) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_inode_lookup: block: %" PRIuDADDR, sect); return 1; } fatfs->dep = (fatfs_dentry *) & fatfs->dinodes[off]; if (fatfs_isdentry(fatfs, fatfs->dep)) { if ((retval = fatfs_dinode_copy(fatfs, a_fs_file->meta, fatfs->dep, sect, inum)) != TSK_OK) { /* If there was a unicode conversion error, * then still return the inode */ if (retval == TSK_ERR) { return 1; } else { if (tsk_verbose) tsk_error_print(stderr); tsk_error_reset(); } } return 0; } else { tsk_error_reset(); tsk_errno = TSK_ERR_FS_INODE_NUM; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_inode_lookup: %" PRIuINUM " is not an inode", inum); return 1; }}/** \internal * Process the file and load up the clusters into the FS_DATA attribute * in fs_meta. The run will list the starting sector and length in sectors * * @param a_fs_file File to process and structore to store results in * * @returns 1 on error and 0 on success */uint8_tfatfs_make_data_run(TSK_FS_FILE * a_fs_file){ TSK_FS_INFO *fs; TSK_DADDR_T clust; TSK_OFF_T size_remain; TSK_FS_ATTR *fs_attr = NULL; TSK_FS_META *fs_meta; FATFS_INFO *fatfs; if ((a_fs_file == NULL) || (a_fs_file->meta == NULL) || (a_fs_file->fs_info == NULL)) { tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_make_data_run: called with NULL pointers"); return 1; } fs_meta = a_fs_file->meta; fs = a_fs_file->fs_info; fatfs = (FATFS_INFO *) fs; clust = ((TSK_DADDR_T *) fs_meta->content_ptr)[0]; size_remain = fs_meta->size; // see if we have already loaded the runs if ((fs_meta->attr != NULL) && (fs_meta->attr_state == TSK_FS_META_ATTR_STUDIED)) { return 0; } else if (fs_meta->attr_state == TSK_FS_META_ATTR_ERROR) { return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -