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

📄 fatfs_meta.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    // not sure why this would ever happen, but...    else if (fs_meta->attr != NULL) {        tsk_fs_attrlist_markunused(fs_meta->attr);    }    else if (fs_meta->attr == NULL) {        fs_meta->attr = tsk_fs_attrlist_alloc();    }    // sanity check on input    if ((clust > (fatfs->lastclust)) &&        (FATFS_ISEOF(clust, fatfs->mask) == 0)) {        fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;        tsk_error_reset();        if (a_fs_file->meta->flags & TSK_FS_META_FLAG_UNALLOC)            tsk_errno = TSK_ERR_FS_RECOVER;        else            tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "fatfs_make_data_run: Starting cluster address too large: %"            PRIuDADDR, clust);        return 1;    }    /* We need to handle the special files specially because they      * are not in the FAT.  Except for FAT32 root dirs, those are normal.     */    if ((a_fs_file->meta->addr == FATFS_ROOTINO)        && (fs->ftype != TSK_FS_TYPE_FAT32) && (clust == 1)) {        TSK_FS_ATTR_RUN *data_run;        if (tsk_verbose)            tsk_fprintf(stderr,                "fatfs_make_data_run: Loading root directory\n");        // make a non-resident run        data_run = tsk_fs_attr_run_alloc();        if (data_run == NULL) {            return 1;        }        data_run->addr = fatfs->rootsect;        data_run->len = fatfs->firstclustsect - fatfs->firstdatasect;        if ((fs_attr =                tsk_fs_attrlist_getnew(fs_meta->attr,                    TSK_FS_ATTR_NONRES)) == NULL) {            return 1;        }        // initialize the data run        if (tsk_fs_attr_set_run(a_fs_file, fs_attr, data_run, NULL,                TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,                data_run->len * fs->block_size,                data_run->len * fs->block_size, 0, 0)) {            return 1;        }        fs_meta->attr_state = TSK_FS_META_ATTR_STUDIED;        return 0;    }    // see if it is one of the special files    else if ((a_fs_file->meta->addr > fs->last_inum - FATFS_NUM_SPECFILE)        && (a_fs_file->meta->addr != TSK_FS_ORPHANDIR_INUM(fs))) {        TSK_FS_ATTR_RUN *data_run;        if (tsk_verbose)            tsk_fprintf(stderr,                "fatfs_make_data_run: Loading special file: %" PRIuINUM                "\n", a_fs_file->meta->addr);        // make a non-resident run        data_run = tsk_fs_attr_run_alloc();        if (data_run == NULL) {            return 1;        }        data_run->addr = clust;        data_run->len = a_fs_file->meta->size / fs->block_size;        if ((fs_attr =                tsk_fs_attrlist_getnew(fs_meta->attr,                    TSK_FS_ATTR_NONRES)) == NULL) {            return 1;        }        // initialize the data run        if (tsk_fs_attr_set_run(a_fs_file, fs_attr, data_run, NULL,                TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,                data_run->len * fs->block_size,                data_run->len * fs->block_size, 0, 0)) {            return 1;        }        fs_meta->attr_state = TSK_FS_META_ATTR_STUDIED;        return 0;    }    /* A deleted file that we want to recover      * In this case, we could get a lot of errors because of inconsistent     * data.  TO make it clear that these are from a recovery, we set most     * error codes to _RECOVER so that they can be more easily suppressed.     */    else if (fs_meta->flags & TSK_FS_META_FLAG_UNALLOC) {        TSK_DADDR_T sbase;        TSK_DADDR_T startclust = clust;        TSK_OFF_T recoversize = fs_meta->size;        int retval;        TSK_FS_ATTR_RUN *data_run = NULL;        TSK_FS_ATTR_RUN *data_run_head = NULL;        TSK_OFF_T full_len_s = 0;        uint8_t canRecover = 1; // set to 0 if recovery is not possible        if (tsk_verbose)            tsk_fprintf(stderr,                "fatfs_make_data_run: Processing deleted file %" PRIuINUM                " in recovery mode\n", fs_meta->addr);        /* We know the size and the starting cluster         *         * We are going to take the clusters from the starting cluster         * onwards and skip the clusters that are current allocated         */        /* Sanity checks on the starting cluster */        /* Convert the cluster addr to a sector addr */        sbase = FATFS_CLUST_2_SECT(fatfs, startclust);        if (sbase > fs->last_block) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_RECOVER;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "fatfs_make_data_run: Starting cluster address too large (recovery): %"                PRIuDADDR, sbase);            fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;            return 1;        }        else {            /* If the starting cluster is already allocated then we can't             * recover it */            retval = fatfs_is_clustalloc(fatfs, startclust);            if (retval != 0) {                canRecover = 0;            }        }        /* Part 1 is to make sure there are enough unallocated clusters         * for the size of the file          */        clust = startclust;        size_remain = recoversize;        // we could make this negative so sign it for the comparison        while (((int64_t) size_remain > 0) && (canRecover)) {            int retval;            sbase = FATFS_CLUST_2_SECT(fatfs, clust);            /* Are we past the end of the FS?              * that means we could not find enough unallocated clusters             * for the file size */            if (sbase > fs->last_block) {                canRecover = 0;                if (tsk_verbose)                    tsk_fprintf(stderr,                        "Could not find enough unallocated sectors to recover with - aborting\n");                break;            }            /* Skip allocated clusters */            retval = fatfs_is_clustalloc(fatfs, clust);            if (retval == -1) {                canRecover = 0;                break;            }            else if (retval == 1) {                clust++;                continue;            }            /* We can use this sector */            // see if we need a new run            if ((data_run == NULL)                || (data_run->addr + data_run->len != sbase)) {                TSK_FS_ATTR_RUN *data_run_tmp = tsk_fs_attr_run_alloc();                if (data_run_tmp == NULL) {                    fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                    tsk_fs_attr_run_free(data_run_head);                    return 1;                }                if (data_run_head == NULL) {                    data_run_head = data_run_tmp;                    data_run_tmp->offset = 0;                }                else if (data_run != NULL) {                    data_run->next = data_run_tmp;                    data_run_tmp->offset =                        data_run->offset + data_run->len;                }                data_run = data_run_tmp;                data_run->len = 0;                data_run->addr = sbase;            }            data_run->len += fatfs->csize;            full_len_s += fatfs->csize;            size_remain -= (fatfs->csize << fatfs->ssize_sh);            clust++;        }        // Get a FS_DATA structure and add the runlist to it        if ((fs_attr =                tsk_fs_attrlist_getnew(fs_meta->attr,                    TSK_FS_ATTR_NONRES)) == NULL) {            fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;            return 1;        }        if (canRecover) {            /* We can recover the file */            // initialize the data run            if (tsk_fs_attr_set_run(a_fs_file, fs_attr, data_run_head,                    NULL, TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,                    fs_meta->size, roundup(fs_meta->size,                        fs->block_size), 0, 0)) {                fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                return 1;            }            fs_meta->attr_state = TSK_FS_META_ATTR_STUDIED;        }        // create a one cluster run        else {            TSK_FS_ATTR_RUN *data_run_tmp = tsk_fs_attr_run_alloc();            if (data_run_tmp == NULL) {                fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                return 1;            }            data_run_tmp->addr = sbase;            data_run_tmp->len = fatfs->csize;            // initialize the data run            if (tsk_fs_attr_set_run(a_fs_file, fs_attr, data_run_tmp, NULL,                    TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,                    fs_meta->size, roundup(fs_meta->size,                        fs->block_size), 0, 0)) {                fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                return 1;            }            fs_meta->attr_state = TSK_FS_META_ATTR_STUDIED;        }        return 0;    }    /* Normal cluster chain walking */    else {        TSK_LIST *list_seen = NULL;        TSK_FS_ATTR_RUN *data_run = NULL;        TSK_FS_ATTR_RUN *data_run_head = NULL;        TSK_OFF_T full_len_s = 0;        TSK_DADDR_T sbase;        if (tsk_verbose)            tsk_fprintf(stderr,                "fatfs_make_data_run: Processing file %" PRIuINUM                " in normal mode\n", fs_meta->addr);        /* Cycle through the cluster chain */        while ((clust & fatfs->mask) > 0 && (int64_t) size_remain > 0 &&            (0 == FATFS_ISEOF(clust, fatfs->mask))) {            /* Convert the cluster addr to a sector addr */            sbase = FATFS_CLUST_2_SECT(fatfs, clust);            if (sbase > fs->last_block) {                fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                tsk_error_reset();                tsk_errno = TSK_ERR_FS_INODE_COR;                snprintf(tsk_errstr, TSK_ERRSTR_L,                    "fatfs_make_data_run: Invalid sector address in FAT (too large): %"                    PRIuDADDR, sbase);                return 1;            }            // see if we need a new run            if ((data_run == NULL)                || (data_run->addr + data_run->len != sbase)) {                TSK_FS_ATTR_RUN *data_run_tmp = tsk_fs_attr_run_alloc();                if (data_run_tmp == NULL) {                    tsk_fs_attr_run_free(data_run_head);                    fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                    return 1;                }                if (data_run_head == NULL) {                    data_run_head = data_run_tmp;                    data_run_tmp->offset = 0;                }                else if (data_run != NULL) {                    data_run->next = data_run_tmp;                    data_run_tmp->offset =                        data_run->offset + data_run->len;                }                data_run = data_run_tmp;                data_run->len = 0;                data_run->addr = sbase;            }            data_run->len += fatfs->csize;            full_len_s += fatfs->csize;            size_remain -= (fatfs->csize * fs->block_size);            if ((int64_t) size_remain > 0) {                TSK_DADDR_T nxt;                if (fatfs_getFAT(fatfs, clust, &nxt)) {                    snprintf(tsk_errstr2, TSK_ERRSTR_L,                        "file walk: Inode: %" PRIuINUM "  cluster: %"                        PRIuDADDR, fs_meta->addr, clust);                    fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                    tsk_fs_attr_run_free(data_run_head);                    tsk_list_free(list_seen);                    list_seen = NULL;                    return 1;                }                clust = nxt;                /* Make sure we do not get into an infinite loop */                if (tsk_list_find(list_seen, clust)) {                    if (tsk_verbose)                        tsk_fprintf(stderr,                            "Loop found while processing file\n");                    break;                }                if (tsk_list_add(&list_seen, clust)) {                    fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;                    tsk_list_free(list_seen);                    list_seen = NULL;                    return 1;                }            }        }        // add the run list to the inode structure        if ((fs_attr =                tsk_fs_attrlist_getnew(fs_meta->attr,                    TSK_FS_ATTR_NONRES)) == NULL) {            fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;            return 1;        }        // initialize the data run        if (tsk_fs_attr_set_run(a_fs_file, fs_attr, data_run_head, NULL,                TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,                fs_meta->size, roundup(fs_meta->size, fs->block_size), 0,                0)) {            fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;            return 1;        }        tsk_list_free(list_seen);        list_seen = NULL;        fs_meta->attr_state = TSK_FS_META_ATTR_STUDIED;        return 0;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -