/** * \ingroup fslib * Tries to process data in a disk image at a given offset as a file system. * Returns a structure that can be used for analysis and reporting. * * @param a_img_info Disk image to analyze * @param a_offset Byte offset to start analyzing from * @param a_ftype Type of file system (or autodetect) * * @return NULL on error */ TSK_FS_INFO * tsk_fs_open_img(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_offset, TSK_FS_TYPE_ENUM a_ftype) { if (a_img_info == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_fs_open_img: Null image handle"); return NULL; } /* We will try different file systems ... * We need to try all of them in case more than one matches */ if (a_ftype == TSK_FS_TYPE_DETECT) { TSK_FS_INFO *fs_info, *fs_set = NULL; char *set = NULL; if (tsk_verbose) tsk_fprintf(stderr, "fsopen: Auto detection mode at offset %" PRIuOFF "\n", a_offset); if ((fs_info = ntfs_open(a_img_info, a_offset, TSK_FS_TYPE_NTFS_DETECT, 1)) != NULL) { set = "NTFS"; fs_set = fs_info; } else { tsk_error_reset(); } if ((fs_info = fatfs_open(a_img_info, a_offset, TSK_FS_TYPE_FAT_DETECT, 1)) != NULL) { if (set == NULL) { set = "FAT"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "FAT or %s", set); return NULL; } } else { tsk_error_reset(); } if ((fs_info = ext2fs_open(a_img_info, a_offset, TSK_FS_TYPE_EXT_DETECT, 1)) != NULL) { if (set == NULL) { set = "EXT2/3"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "EXT2/3 or %s", set); return NULL; } } else { tsk_error_reset(); } if ((fs_info = ffs_open(a_img_info, a_offset, TSK_FS_TYPE_FFS_DETECT)) != NULL) { if (set == NULL) { set = "UFS"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "UFS or %s", set); return NULL; } } else { tsk_error_reset(); } #if TSK_USE_HFS if ((fs_info = hfs_open(a_img_info, a_offset, TSK_FS_TYPE_HFS_DETECT, 1)) != NULL) { if (set == NULL) { set = "HFS"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "HFS or %s", set); return NULL; } } else { tsk_error_reset(); } #endif if ((fs_info = iso9660_open(a_img_info, a_offset, TSK_FS_TYPE_ISO9660_DETECT, 1)) != NULL) { if (set != NULL) { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "ISO9660 or %s", set); return NULL; } fs_set = fs_info; } else { tsk_error_reset(); } if (fs_set == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; tsk_errstr[0] = '\0'; tsk_errstr2[0] = '\0'; return NULL; } return fs_set; } else { if (TSK_FS_TYPE_ISNTFS(a_ftype)) return ntfs_open(a_img_info, a_offset, a_ftype, 0); else if (TSK_FS_TYPE_ISFAT(a_ftype)) return fatfs_open(a_img_info, a_offset, a_ftype, 0); else if (TSK_FS_TYPE_ISFFS(a_ftype)) return ffs_open(a_img_info, a_offset, a_ftype); else if (TSK_FS_TYPE_ISEXT(a_ftype)) return ext2fs_open(a_img_info, a_offset, a_ftype, 0); else if (TSK_FS_TYPE_ISHFS(a_ftype)) return hfs_open(a_img_info, a_offset, a_ftype, 0); else if (TSK_FS_TYPE_ISISO9660(a_ftype)) return iso9660_open(a_img_info, a_offset, a_ftype, 0); else if (TSK_FS_TYPE_ISRAW(a_ftype)) return rawfs_open(a_img_info, a_offset); else if (TSK_FS_TYPE_ISSWAP(a_ftype)) return swapfs_open(a_img_info, a_offset); else { tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNSUPTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "%X", (int) a_ftype); return NULL; } } }
TSK_FS_INFO * tsk_fs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, const TSK_TCHAR * type) { /* We will try different file systems ... * We need to try all of them in case more than one matches */ if (type == NULL) { TSK_FS_INFO *fs_info, *fs_set = NULL; char *set = NULL; if (tsk_verbose) tsk_fprintf(stderr, "fsopen: Auto detection mode at offset %" PRIuOFF "\n", offset); if ((fs_info = ntfs_open(img_info, offset, TSK_FS_INFO_TYPE_NTFS_AUTO, 1)) != NULL) { set = "NTFS"; fs_set = fs_info; } else { tsk_error_reset(); } if ((fs_info = fatfs_open(img_info, offset, TSK_FS_INFO_TYPE_FAT_AUTO, 1)) != NULL) { if (set == NULL) { set = "FAT"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "FAT or %s", set); return NULL; } } else { tsk_error_reset(); } if ((fs_info = ext2fs_open(img_info, offset, TSK_FS_INFO_TYPE_EXT_AUTO, 1)) != NULL) { if (set == NULL) { set = "EXT2/3"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "EXT2/3 or %s", set); return NULL; } } else { tsk_error_reset(); } if ((fs_info = ffs_open(img_info, offset, TSK_FS_INFO_TYPE_FFS_AUTO)) != NULL) { if (set == NULL) { set = "UFS"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "UFS or %s", set); return NULL; } } else { tsk_error_reset(); } #if TSK_USE_HFS if ((fs_info = hfs_open(img_info, offset, TSK_FS_INFO_TYPE_HFS, 1)) != NULL) { if (set == NULL) { set = "HFS"; fs_set = fs_info; } else { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "HFS or %s", set); return NULL; } } else { tsk_error_reset(); } #endif if ((fs_info = iso9660_open(img_info, offset, TSK_FS_INFO_TYPE_ISO9660, 1)) != NULL) { if (set != NULL) { fs_set->close(fs_set); fs_info->close(fs_info); tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "ISO9660 or %s", set); return NULL; } fs_set = fs_info; } else { tsk_error_reset(); } if (fs_set == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNKTYPE; tsk_errstr[0] = '\0'; tsk_errstr2[0] = '\0'; return NULL; } return fs_set; } else { uint8_t ftype; ftype = tsk_fs_parse_type(type); switch (ftype & TSK_FS_INFO_TYPE_FS_MASK) { case TSK_FS_INFO_TYPE_FFS_TYPE: return ffs_open(img_info, offset, ftype); case TSK_FS_INFO_TYPE_EXT_TYPE: return ext2fs_open(img_info, offset, ftype, 0); case TSK_FS_INFO_TYPE_FAT_TYPE: return fatfs_open(img_info, offset, ftype, 0); case TSK_FS_INFO_TYPE_NTFS_TYPE: return ntfs_open(img_info, offset, ftype, 0); case TSK_FS_INFO_TYPE_ISO9660_TYPE: return iso9660_open(img_info, offset, ftype, 0); #if 0 case TSK_FS_INFO_TYPE_HFS_TYPE: return hfs_open(img_info, offset, ftype, 0); #endif case TSK_FS_INFO_TYPE_RAW_TYPE: return rawfs_open(img_info, offset); case TSK_FS_INFO_TYPE_SWAP_TYPE: return swapfs_open(img_info, offset); case TSK_FS_INFO_TYPE_UNSUPP: default: tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNSUPTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s", type); return NULL; } } }
/** * \ingroup fslib * Tries to process data in a disk image at a given offset as a file system. * Returns a structure that can be used for analysis and reporting. * * @param a_img_info Disk image to analyze * @param a_offset Byte offset to start analyzing from * @param a_ftype Type of file system (or autodetect) * * @return NULL on error */ TSK_FS_INFO * tsk_fs_open_img(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_offset, TSK_FS_TYPE_ENUM a_ftype) { TSK_FS_INFO *fs_info; const struct { char* name; TSK_FS_INFO* (*open)(TSK_IMG_INFO*, TSK_OFF_T, TSK_FS_TYPE_ENUM, uint8_t); TSK_FS_TYPE_ENUM type; } FS_OPENERS[] = { { "NTFS", ntfs_open, TSK_FS_TYPE_NTFS_DETECT }, { "FAT", fatfs_open, TSK_FS_TYPE_FAT_DETECT }, { "EXT2/3/4", ext2fs_open, TSK_FS_TYPE_EXT_DETECT }, { "UFS", ffs_open, TSK_FS_TYPE_FFS_DETECT }, { "YAFFS2", yaffs2_open, TSK_FS_TYPE_YAFFS2_DETECT }, #if TSK_USE_HFS { "HFS", hfs_open, TSK_FS_TYPE_HFS_DETECT }, #endif { "ISO9660", iso9660_open, TSK_FS_TYPE_ISO9660_DETECT } }; if (a_img_info == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr("tsk_fs_open_img: Null image handle"); return NULL; } /* We will try different file systems ... * We need to try all of them in case more than one matches */ if (a_ftype == TSK_FS_TYPE_DETECT) { unsigned long i; const char *name_first = ""; TSK_FS_INFO *fs_first = NULL; if (tsk_verbose) tsk_fprintf(stderr, "fsopen: Auto detection mode at offset %" PRIuOFF "\n", a_offset); for (i = 0; i < sizeof(FS_OPENERS)/sizeof(FS_OPENERS[0]); ++i) { if ((fs_info = FS_OPENERS[i].open( a_img_info, a_offset, FS_OPENERS[i].type, 1)) != NULL) { // fs opens as type i if (fs_first == NULL) { // first success opening fs name_first = FS_OPENERS[i].name; fs_first = fs_info; } else { // second success opening fs, which means we // cannot autodetect the fs type and must give up fs_first->close(fs_first); fs_info->close(fs_info); tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNKTYPE); tsk_error_set_errstr( "%s or %s", FS_OPENERS[i].name, name_first); return NULL; } } else { // fs does not open as type i tsk_error_reset(); } } if (fs_first == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNKTYPE); } return fs_first; } else if (TSK_FS_TYPE_ISNTFS(a_ftype)) { return ntfs_open(a_img_info, a_offset, a_ftype, 0); } else if (TSK_FS_TYPE_ISFAT(a_ftype)) { return fatfs_open(a_img_info, a_offset, a_ftype, 0); } else if (TSK_FS_TYPE_ISFFS(a_ftype)) { return ffs_open(a_img_info, a_offset, a_ftype, 0); } else if (TSK_FS_TYPE_ISEXT(a_ftype)) { return ext2fs_open(a_img_info, a_offset, a_ftype, 0); } else if (TSK_FS_TYPE_ISHFS(a_ftype)) { return hfs_open(a_img_info, a_offset, a_ftype, 0); } else if (TSK_FS_TYPE_ISISO9660(a_ftype)) { return iso9660_open(a_img_info, a_offset, a_ftype, 0); } else if (TSK_FS_TYPE_ISRAW(a_ftype)) { return rawfs_open(a_img_info, a_offset); } else if (TSK_FS_TYPE_ISSWAP(a_ftype)) { return swapfs_open(a_img_info, a_offset); } else if (TSK_FS_TYPE_ISYAFFS2(a_ftype)) { return yaffs2_open(a_img_info, a_offset, a_ftype, 0); } tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNSUPTYPE); tsk_error_set_errstr("%X", (int) a_ftype); return NULL; }