/** * Utility method to help determine if a file is a FAT file system file (such as $MBR). * * @returns 1 if the file is an FAT System file, 0 if not. */ uint8_t TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file) { if ((a_fs_file) && (a_fs_file->fs_info) && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype)) && (a_fs_file->name->meta_addr == FATFS_MBRINO(a_fs_file->fs_info) || a_fs_file->name->meta_addr == FATFS_FAT1INO(a_fs_file->fs_info) || a_fs_file->name->meta_addr == FATFS_FAT2INO(a_fs_file->fs_info))) return 1; else return 0; }
TSK_RETVAL_ENUM fatfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir, TSK_INUM_T a_addr) { TSK_OFF_T size, len; FATFS_INFO *fatfs = (FATFS_INFO *) a_fs; char *dirbuf; TSK_DADDR_T *addrbuf; FATFS_LOAD_DIR load; int retval; TSK_FS_DIR *fs_dir; if ((a_addr < a_fs->first_inum) || (a_addr > a_fs->last_inum)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_WALK_RNG); tsk_error_set_errstr("fatfs_dir_open_meta: invalid a_addr value: %" PRIuINUM "\n", a_addr); return TSK_ERR; } else if (a_fs_dir == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("fatfs_dir_open_meta: NULL fs_attr argument given"); return TSK_ERR; } fs_dir = *a_fs_dir; if (fs_dir) { tsk_fs_dir_reset(fs_dir); } else { if ((*a_fs_dir = fs_dir = tsk_fs_dir_alloc(a_fs, a_addr, 128)) == NULL) { return TSK_ERR; } } // handle the orphan directory if its contents were requested if (a_addr == TSK_FS_ORPHANDIR_INUM(a_fs)) { return tsk_fs_dir_find_orphans(a_fs, fs_dir); } fs_dir->fs_file = tsk_fs_file_open_meta(a_fs, NULL, a_addr); if (fs_dir->fs_file == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_INODE_NUM); tsk_error_set_errstr("fatfs_dir_open_meta: %" PRIuINUM " is not a valid inode", a_addr); return TSK_COR; } size = fs_dir->fs_file->meta->size; len = roundup(size, fatfs->ssize); if (tsk_verbose) tsk_fprintf(stderr, "fatfs_dir_open_meta: Processing directory %" PRIuINUM "\n", a_addr); if (size == 0) { if (tsk_verbose) tsk_fprintf(stderr, "fatfs_dir_open_meta: directory has 0 size\n"); return TSK_OK; } /* Make a copy of the directory contents using file_walk */ if ((dirbuf = tsk_malloc((size_t) len)) == NULL) { return TSK_ERR; } load.curdirptr = dirbuf; load.dirleft = (size_t) size; /* We are going to save the address of each sector in the directory * in a stack - they are needed to determine the inode address. */ load.addrsize = (size_t) (len / fatfs->ssize); addrbuf = (TSK_DADDR_T *) tsk_malloc(load.addrsize * sizeof(TSK_DADDR_T)); if (addrbuf == NULL) { free(dirbuf); return TSK_ERR; } /* Set the variables that are used during the copy */ load.addridx = 0; load.addrbuf = addrbuf; /* save the directory contents into dirbuf */ if (tsk_fs_file_walk(fs_dir->fs_file, TSK_FS_FILE_WALK_FLAG_SLACK, fatfs_dent_action, (void *) &load)) { tsk_error_errstr2_concat("- fatfs_dir_open_meta"); free(dirbuf); free(addrbuf); return TSK_COR; } /* We did not copy the entire directory, which occurs if an error occured */ if (load.dirleft > 0) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_FWALK); tsk_error_set_errstr ("fatfs_dir_open_meta: Error reading directory %" PRIuINUM, a_addr); /* Free the local buffers */ free(dirbuf); free(addrbuf); return TSK_COR; } if (tsk_verbose) fprintf(stderr, "fatfs_dir_open_meta: Parsing directory %" PRIuINUM "\n", a_addr); retval = fatfs_dent_parse_buf(fatfs, fs_dir, dirbuf, len, addrbuf); free(dirbuf); free(addrbuf); // if we are listing the root directory, add the Orphan directory and special FAT file entries if (a_addr == a_fs->root_inum) { TSK_FS_NAME *fs_name = tsk_fs_name_alloc(256, 0); if (fs_name == NULL) return TSK_ERR; // MBR Entry strncpy(fs_name->name, FATFS_MBRNAME, fs_name->name_size); fs_name->meta_addr = FATFS_MBRINO(a_fs); fs_name->type = TSK_FS_NAME_TYPE_VIRT; 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; } // FAT1 Entry strncpy(fs_name->name, FATFS_FAT1NAME, fs_name->name_size); fs_name->meta_addr = FATFS_FAT1INO(a_fs); fs_name->type = TSK_FS_NAME_TYPE_VIRT; 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; } // FAT2 Entry strncpy(fs_name->name, FATFS_FAT2NAME, fs_name->name_size); fs_name->meta_addr = FATFS_FAT2INO(a_fs); fs_name->type = TSK_FS_NAME_TYPE_VIRT; 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; } // orphan directory if (tsk_fs_dir_make_orphan_dir_name(a_fs, fs_name)) { tsk_fs_name_free(fs_name); return TSK_ERR; } if (tsk_fs_dir_add(fs_dir, fs_name)) { tsk_fs_name_free(fs_name); return TSK_ERR; } tsk_fs_name_free(fs_name); } return retval; }