📄 fatfs.c
字号:
free(fatfs->dinodes); if (fatfs->dir_buf) free(fatfs->dir_buf); if (fatfs->par_buf) free(fatfs->par_buf); tsk_list_free(fs->list_inum_named); fs->list_inum_named = NULL; free(fatfs->sb); free(fs);}/** * \internal * Open part of a disk image as a FAT file system. * * @param img_info Disk image to analyze * @param offset Byte offset where FAT file system starts * @param ftype Specific type of FAT file system * @param test NOT USED * @returns NULL on error or if data is not a FAT file system */TSK_FS_INFO *fatfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, TSK_FS_TYPE_ENUM ftype, uint8_t test){ char *myname = "fatfs_open"; FATFS_INFO *fatfs; unsigned int len; TSK_FS_INFO *fs; fatfs_sb *fatsb; TSK_DADDR_T sectors; ssize_t cnt; int i; // clean up any error messages that are lying around tsk_error_reset(); if (TSK_FS_TYPE_ISFAT(ftype) == 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: Invalid FS Type", myname); return NULL; } if ((fatfs = (FATFS_INFO *) tsk_malloc(sizeof(*fatfs))) == NULL) return NULL; fs = &(fatfs->fs_info); fs->ftype = ftype; fs->img_info = img_info; fs->offset = offset; fs->tag = TSK_FS_INFO_TAG; /* * Read the super block. */ len = sizeof(fatfs_sb); fatsb = fatfs->sb = (fatfs_sb *) tsk_malloc(len); if (fatsb == NULL) { fs->tag = 0; free(fatfs); return NULL; } /* Look for the boot sector. We loop because * we will try the backup if the first fails. * Only FAT32 has a backup though...*/ for (i = 0; i < 2; i++) { TSK_OFF_T sb_off; if (i == 0) sb_off = 0; else sb_off = 6 * 512; // the backup is located in sector 6 cnt = tsk_fs_read(fs, sb_off, (char *) fatsb, len); if (cnt != len) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "%s: boot sector", myname); fs->tag = 0; free(fatfs->sb); free(fatfs); return NULL; } /* Check the magic value and ID endian ordering */ if (tsk_fs_guessu16(fs, fatsb->magic, FATFS_FS_MAGIC)) { // if the magic value is 0, then we will try the backup if ((i == 0) && (tsk_getu16(TSK_LIT_ENDIAN, fatsb->magic) == 0)) { continue; } else { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Not a FATFS file system (magic)"); return NULL; } } else { break; } } fs->dev_bsize = FATFS_DEV_BSIZE; /* Calculate block sizes and layout info */ // sector size fatfs->ssize = tsk_getu16(fs->endian, fatsb->ssize); if (fatfs->ssize == 512) { fatfs->ssize_sh = 9; } else if (fatfs->ssize == 1024) { fatfs->ssize_sh = 10; } else if (fatfs->ssize == 2048) { fatfs->ssize_sh = 11; } else if (fatfs->ssize == 4096) { fatfs->ssize_sh = 12; } else { tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Error: sector size (%d) is not a multiple of device size (%d)\nDo you have a disk image instead of a partition image?", fatfs->ssize, fs->dev_bsize); fs->tag = 0; free(fatsb); free(fatfs); return NULL; } // cluster size fatfs->csize = fatsb->csize; if ((fatfs->csize != 0x01) && (fatfs->csize != 0x02) && (fatfs->csize != 0x04) && (fatfs->csize != 0x08) && (fatfs->csize != 0x10) && (fatfs->csize != 0x20) && (fatfs->csize != 0x40) && (fatfs->csize != 0x80)) { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Not a FATFS file system (cluster size)"); return NULL; } // number of FAT tables fatfs->numfat = fatsb->numfat; if ((fatfs->numfat == 0) || (fatfs->numfat > 8)) { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Not a FATFS file system (number of FATs)"); return NULL; } /* We can't do a sanity check on this b.c. TSK_FS_TYPE_FAT32 has a value of 0 */ /* num of root entries */ fatfs->numroot = tsk_getu16(fs->endian, fatsb->numroot); /* if sectors16 is 0, then the number of sectors is stored in sectors32 */ if (0 == (sectors = tsk_getu16(fs->endian, fatsb->sectors16))) sectors = tsk_getu32(fs->endian, fatsb->sectors32); /* if secperfat16 is 0, then read sectperfat32 */ if (0 == (fatfs->sectperfat = tsk_getu16(fs->endian, fatsb->sectperfat16))) fatfs->sectperfat = tsk_getu32(fs->endian, fatsb->a.f32.sectperfat32); if (fatfs->sectperfat == 0) { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Not a FATFS file system (invalid sectors per FAT)"); return NULL; } fatfs->firstfatsect = tsk_getu16(fs->endian, fatsb->reserved); if ((fatfs->firstfatsect == 0) || (fatfs->firstfatsect > sectors)) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "Not a FATFS file system (invalid first FAT sector %" PRIuDADDR ")", fatfs->firstfatsect); fs->tag = 0; free(fatsb); free(fatfs); return NULL; } /* Calculate the block info * * The sector of the begining of the data area - which is * after all of the FATs * * For TSK_FS_TYPE_FAT12 and TSK_FS_TYPE_FAT16, the data area starts with the root * directory entries and then the first cluster. For TSK_FS_TYPE_FAT32, * the data area starts with clusters and the root directory * is somewhere in the data area */ fatfs->firstdatasect = fatfs->firstfatsect + fatfs->sectperfat * fatfs->numfat; /* The sector where the first cluster is located. It will be used * to translate cluster addresses to sector addresses * * For TSK_FS_TYPE_FAT32, the first cluster is the start of the data area and * it is after the root directory for TSK_FS_TYPE_FAT12 and TSK_FS_TYPE_FAT16. At this * point in the program, numroot is set to 0 for TSK_FS_TYPE_FAT32 */ fatfs->firstclustsect = fatfs->firstdatasect + ((fatfs->numroot * 32 + fatfs->ssize - 1) / fatfs->ssize); /* total number of clusters */ fatfs->clustcnt = (sectors - fatfs->firstclustsect) / fatfs->csize; /* the first cluster is #2, so the final cluster is: */ fatfs->lastclust = 1 + fatfs->clustcnt; /* identify the FAT type by the total number of data clusters * this calculation is from the MS FAT Overview Doc * * A FAT file system made by another OS could use different values */ if (ftype == TSK_FS_TYPE_FAT_DETECT) { if (fatfs->clustcnt < 4085) { ftype = TSK_FS_TYPE_FAT12; } else if (fatfs->clustcnt < 65525) { ftype = TSK_FS_TYPE_FAT16; } else { ftype = TSK_FS_TYPE_FAT32; } fatfs->fs_info.ftype = ftype; } /* Some sanity checks */ else { if ((ftype == TSK_FS_TYPE_FAT12) && (fatfs->clustcnt >= 4085)) { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Too many sectors for TSK_FS_TYPE_FAT12: try auto-detect mode"); return NULL; } } if ((ftype == TSK_FS_TYPE_FAT32) && (fatfs->numroot != 0)) { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Invalid TSK_FS_TYPE_FAT32 image (numroot != 0)"); return NULL; } if ((ftype != TSK_FS_TYPE_FAT32) && (fatfs->numroot == 0)) { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Invalid FAT image (numroot == 0, and not TSK_FS_TYPE_FAT32)"); return NULL; } /* Set the mask to use on the cluster values */ if (ftype == TSK_FS_TYPE_FAT12) { fatfs->mask = FATFS_12_MASK; } else if (ftype == TSK_FS_TYPE_FAT16) { fatfs->mask = FATFS_16_MASK; } else if (ftype == TSK_FS_TYPE_FAT32) { fatfs->mask = FATFS_32_MASK; } else { fs->tag = 0; free(fatsb); free(fatfs); tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "Unknown FAT type in fatfs_open: %d\n", ftype); return NULL; } fs->duname = "Sector"; /* the root directories are always after the FAT for TSK_FS_TYPE_FAT12 and TSK_FS_TYPE_FAT16, * but are dynamically located for TSK_FS_TYPE_FAT32 */ if (ftype == TSK_FS_TYPE_FAT32) fatfs->rootsect = FATFS_CLUST_2_SECT(fatfs, tsk_getu32(fs->endian, fatsb->a.f32.rootclust)); else fatfs->rootsect = fatfs->firstdatasect; for (i = 0; i < FAT_CACHE_N; i++) { fatfs->fatc_addr[i] = 0; fatfs->fatc_ttl[i] = 0; } /* allocate a cluster-sized buffer for inodes */ if ((fatfs->dinodes = (char *) tsk_malloc(fatfs->csize << fatfs->ssize_sh)) == NULL) { fs->tag = 0; free(fatsb); free(fatfs); return NULL; } /* * block calculations : although there are no blocks in fat, we will * use these fields for sector calculations */ fs->first_block = 0; fs->block_count = sectors; fs->last_block = fs->last_block_act = fs->block_count - 1; fs->block_size = fatfs->ssize; // determine the last block we have in this image if ((TSK_DADDR_T) ((img_info->size - offset) / fs->block_size) < fs->block_count) fs->last_block_act = (img_info->size - offset) / fs->block_size - 1; /* * inode calculations */ /* maximum number of dentries in a sector & cluster */ fatfs->dentry_cnt_se = fatfs->ssize / sizeof(fatfs_dentry); fatfs->dentry_cnt_cl = fatfs->dentry_cnt_se * fatfs->csize; fs->root_inum = FATFS_ROOTINO; fs->first_inum = FATFS_FIRSTINO; // Add on extras for Orphan and special files fs->last_inum = (FATFS_SECT_2_INODE(fatfs, fs->last_block_act + 1) - 1) + FATFS_NUM_SPECFILE; fs->inum_count = fs->last_inum - fs->first_inum + 1; /* Volume ID */ for (fs->fs_id_used = 0; fs->fs_id_used < 4; fs->fs_id_used++) { if (ftype == TSK_FS_TYPE_FAT32) fs->fs_id[fs->fs_id_used] = fatsb->a.f32.vol_id[fs->fs_id_used]; else fs->fs_id[fs->fs_id_used] = fatsb->a.f16.vol_id[fs->fs_id_used]; } /* * Set the function pointers */ fs->block_walk = fatfs_block_walk; fs->block_getflags = fatfs_block_getflags; fs->inode_walk = fatfs_inode_walk; fs->istat = fatfs_istat; fs->file_add_meta = fatfs_inode_lookup; fs->get_default_attr_type = fatfs_get_default_attr_type; fs->load_attrs = fatfs_make_data_run; fs->dir_open_meta = fatfs_dir_open_meta; fs->fsstat = fatfs_fsstat; fs->fscheck = fatfs_fscheck; fs->close = fatfs_close; fs->jblk_walk = fatfs_jblk_walk; fs->jentry_walk = fatfs_jentry_walk; fs->jopen = fatfs_jopen; fs->journ_inum = 0; // initialize the caches fs->list_inum_named = NULL; return (fs);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -