⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatfs.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -