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

📄 fatfs_meta.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            return 0;        else if ((tsk_getu16(fs->endian, de->adate) != 0) &&            (FATFS_ISDATE(tsk_getu16(fs->endian, de->adate)) == 0))            return 0;        else if (FATFS_ISDATE(tsk_getu16(fs->endian, de->wdate)) == 0)            return 0;        /* verify the starting cluster is small enough */        else if ((FATFS_DENTRY_CLUST(fs, de) > (fatfs->lastclust)) &&            (FATFS_ISEOF(FATFS_DENTRY_CLUST(fs, de), fatfs->mask) == 0))            return 0;        /* Verify the file size is smaller than the data area */        else if (tsk_getu32(fs->endian, de->size) >            ((fatfs->clustcnt * fatfs->csize) << fatfs->ssize_sh))            return 0;        return is_83_name(de);        //return 1;    }}/************************************************************************** * * INODE WALKING *  *************************************************************************//* Mark the sector used in the bitmap */static TSK_WALK_RET_ENUMinode_walk_file_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off,    TSK_DADDR_T addr, char *buf, size_t size,    TSK_FS_BLOCK_FLAG_ENUM a_flags, void *a_ptr){    setbit((uint8_t *) a_ptr, addr);    return TSK_WALK_CONT;}/* The inode_walk call back for each file.  we want only the directories */static TSK_WALK_RET_ENUMinode_walk_dent_act(TSK_FS_FILE * fs_file, const char *a_path, void *a_ptr){    if ((fs_file->meta == NULL)        || (fs_file->meta->type != TSK_FS_META_TYPE_DIR))        return TSK_WALK_CONT;    /* Get the sector addresses & ignore any errors */    if (tsk_fs_file_walk(fs_file,            TSK_FS_FILE_WALK_FLAG_SLACK | TSK_FS_FILE_WALK_FLAG_AONLY,            inode_walk_file_act, a_ptr)) {        tsk_error_reset();    }    return TSK_WALK_CONT;}/* * walk the inodes * * Flags that are used: TSK_FS_META_FLAG_ALLOC, TSK_FS_META_FLAG_UNALLOC, * TSK_FS_META_FLAG_USED, TSK_FS_META_FLAG_UNUSED, TSK_FS_META_FLAG_ORPHAN * */uint8_tfatfs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum,    TSK_INUM_T end_inum, TSK_FS_META_FLAG_ENUM a_flags,    TSK_FS_META_WALK_CB a_action, void *a_ptr){    char *myname = "fatfs_inode_walk";    FATFS_INFO *fatfs = (FATFS_INFO *) fs;    TSK_INUM_T end_inum_tmp;    TSK_FS_FILE *fs_file;    TSK_DADDR_T sect, ssect, lsect;    fatfs_dentry *dep;    unsigned int myflags, didx;    uint8_t *sect_alloc;    ssize_t cnt;    uint8_t done = 0;    // clean up any error messages that are lying around    tsk_error_reset();    /*     * Sanity checks.     */    if (start_inum < fs->first_inum || start_inum > fs->last_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: Start inode:  %" PRIuINUM "", myname, start_inum);        return 1;    }    else if (end_inum < fs->first_inum || end_inum > fs->last_inum        || end_inum < start_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "%s: End inode: %" PRIuINUM "", myname, end_inum);        return 1;    }    if (tsk_verbose)        tsk_fprintf(stderr,            "fatfs_inode_walk: Inode Walking %" PRIuINUM " to %"            PRIuINUM "\n", start_inum, end_inum);    /* If ORPHAN is wanted, then make sure that the a_flags are correct */    if (a_flags & TSK_FS_META_FLAG_ORPHAN) {        a_flags |= TSK_FS_META_FLAG_UNALLOC;        a_flags &= ~TSK_FS_META_FLAG_ALLOC;        a_flags |= TSK_FS_META_FLAG_USED;        a_flags &= ~TSK_FS_META_FLAG_UNUSED;    }    else {        if (((a_flags & TSK_FS_META_FLAG_ALLOC) == 0) &&            ((a_flags & TSK_FS_META_FLAG_UNALLOC) == 0)) {            a_flags |= (TSK_FS_META_FLAG_ALLOC | TSK_FS_META_FLAG_UNALLOC);        }        /* If neither of the USED or UNUSED a_flags are set, then set them          * both         */        if (((a_flags & TSK_FS_META_FLAG_USED) == 0) &&            ((a_flags & TSK_FS_META_FLAG_UNUSED) == 0)) {            a_flags |= (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_UNUSED);        }    }    /* If we are looking for orphan files and have not yet filled     * in the list of unalloc inodes that are pointed to, then fill     * in the list      */    if ((a_flags & TSK_FS_META_FLAG_ORPHAN)        && (fs->list_inum_named == NULL)) {        if (tsk_fs_dir_load_inum_named(fs) != TSK_OK) {            strncat(tsk_errstr2,                " - fatfs_inode_walk: identifying inodes allocated by file names",                TSK_ERRSTR_L);            return 1;        }    }    if ((fs_file = tsk_fs_file_alloc(fs)) == NULL)        return 1;    if ((fs_file->meta =            tsk_fs_meta_alloc(FATFS_FILE_CONTENT_LEN)) == NULL)        return 1;    // handle the root directory    if (start_inum == FATFS_ROOTINO) {        if (((TSK_FS_META_FLAG_ALLOC & a_flags) == TSK_FS_META_FLAG_ALLOC)            && ((TSK_FS_META_FLAG_USED & a_flags) == TSK_FS_META_FLAG_USED)            && ((TSK_FS_META_FLAG_ORPHAN & a_flags) == 0)) {            int retval;            if (fatfs_make_root(fatfs, fs_file->meta)) {                tsk_fs_file_close(fs_file);                return 1;            }            retval = a_action(fs_file, a_ptr);            if (retval == TSK_WALK_STOP) {                tsk_fs_file_close(fs_file);                return 0;            }            else if (retval == TSK_WALK_ERROR) {                tsk_fs_file_close(fs_file);                return 1;            }        }        /* advance it so that it is a valid starting point */        start_inum++;        // exit if that is all that was requested         if (start_inum == end_inum) {            tsk_fs_file_close(fs_file);            return 0;        }    }    /* We will be looking at each sector to see if it contains directory     * entries.  We can make mistakes and ignore sectors that have valid     * entries in them.  To make sure we at least get all sectors that     * are allocated by directories in the directory tree, we will     * run name_walk and then a file walk on each dir.      * We'll be make sure to print those.  We skip this for ORPHAN hunting     * because it doesn't help and can introduce infinite loop situations       * inode_walk was called by the function that determines which inodes     * are orphans. */    if (tsk_verbose)        tsk_fprintf(stderr,            "fatfs_inode_walk: Walking directories to collect sector info\n");    if ((sect_alloc =            (uint8_t *) tsk_malloc((size_t) ((fs->block_count +                        7) / 8))) == NULL) {        tsk_fs_file_close(fs_file);        return 1;    }    if ((a_flags & TSK_FS_META_FLAG_ORPHAN) == 0) {        // Do a file_walk on the root directory to get its layout        if (fatfs_make_root(fatfs, fs_file->meta)) {            tsk_fs_file_close(fs_file);            free(sect_alloc);            return 1;        }        if (tsk_fs_file_walk(fs_file,                TSK_FS_FILE_WALK_FLAG_SLACK | TSK_FS_FILE_WALK_FLAG_AONLY,                inode_walk_file_act, (void *) sect_alloc)) {            tsk_fs_file_close(fs_file);            free(sect_alloc);            return 1;        }        // now get the rest of the directories.         if (tsk_fs_dir_walk(fs, fs->root_inum,                TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE |                TSK_FS_DIR_WALK_FLAG_NOORPHAN, inode_walk_dent_act,                (void *) sect_alloc)) {            strncat(tsk_errstr2,                " - fatfs_inode_walk: mapping directories", TSK_ERRSTR_L);            tsk_fs_file_close(fs_file);            free(sect_alloc);            return 1;        }    }    /* start analyzing each sector     *     * Perform a test on the first 32 bytes of each sector to identify if     * the sector contains directory entries.  If it does, then continue     * to analyze it.  If not, then read the next sector      */    /* identify the starting and ending inodes sector addrs */    /* we need to handle end_inum specially if it is for the      * virtual ORPHANS directory or virtual FAT files.       * Handle these outside of the loop. */    if (end_inum > fs->last_inum - FATFS_NUM_SPECFILE)        end_inum_tmp = fs->last_inum - FATFS_NUM_SPECFILE;    else        end_inum_tmp = end_inum;    ssect = FATFS_INODE_2_SECT(fatfs, start_inum);    lsect = FATFS_INODE_2_SECT(fatfs, end_inum_tmp);    if (ssect > fs->last_block) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "fatfs_inode_walk: Starting inode in sector too big for image: %"            PRIuDADDR, ssect);        tsk_fs_file_close(fs_file);        free(sect_alloc);        return 1;    }    else if (lsect > fs->last_block) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "fatfs_inode_walk: Ending inode in sector too big for image: %"            PRIuDADDR, lsect);        tsk_fs_file_close(fs_file);        free(sect_alloc);        return 1;    }    sect = ssect;    while (sect <= lsect) {        int clustalloc;         // 1 if current sector / cluster is allocated        size_t sect_proc;       // number of sectors read for this loop        size_t sidx;            // sector index for loop        /* This occurs for the root directory of TSK_FS_TYPE_FAT12/16          *          * We are going to process the image in clusters, so take care of the root         * directory seperately.         */        if (sect < fatfs->firstclustsect) {            // there are no orphans in the root directory            if ((a_flags & TSK_FS_META_FLAG_ORPHAN) != 0) {                sect = fatfs->firstclustsect;                continue;            }            clustalloc = 1;            /* read the sector */            cnt =                tsk_fs_read_block(fs, sect, fatfs->dinodes, fatfs->ssize);            if (cnt != fatfs->ssize) {                if (cnt >= 0) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_READ;                }                snprintf(tsk_errstr2, TSK_ERRSTR_L,                    "fatfs_inode_walk (root dir): sector: %" PRIuDADDR,                    sect);                tsk_fs_file_close(fs_file);                free(sect_alloc);                return 1;            }            sect_proc = 1;        }        /* For the data area, we will read in cluster-sized chunks */        else {            /* get the base sector for the cluster in which the first inode exists */            sect =                FATFS_CLUST_2_SECT(fatfs, (FATFS_SECT_2_CLUST(fatfs,                        sect)));            /* if the cluster is not allocated, then do not go into it if we              * only want allocated/link entries             * If it is allocated, then go into it no matter what             */            clustalloc = fatfs_is_sectalloc(fatfs, sect);            if (clustalloc == -1) {                tsk_fs_file_close(fs_file);                free(sect_alloc);                return 1;            }            else if ((clustalloc == 0)                && ((a_flags & TSK_FS_META_FLAG_UNALLOC) == 0)) {                sect += fatfs->csize;                continue;            }            /* If it is allocated, but we know it is not allocated to a             * directory then skip it.  NOTE: This will miss unallocated             * entries in slack space of the file...             */            if ((clustalloc == 1) && (isset(sect_alloc, sect) == 0)) {                sect += fatfs->csize;                continue;            }            /* The final cluster may not be full */            if (lsect - sect + 1 < fatfs->csize)                sect_proc = (size_t) (lsect - sect + 1);            else                sect_proc = fatfs->csize;            /* read the full cluster */            cnt = tsk_fs_read_block                (fs, sect, fatfs->dinodes, sect_proc << fatfs->ssize_sh);            if (cnt != (sect_proc << fatfs->ssize_sh)) {                if (cnt >= 0) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_READ;                }                snprintf(tsk_errstr2, TSK_ERRSTR_L,                    "fatfs_inode_walk: sector: %" PRIuDADDR, sect);                tsk_fs_file_close(fs_file);                free(sect_alloc);                return 1;            }        }        // cycle through the sectors read        for (sidx = 0; sidx < sect_proc; sidx++) {            TSK_INUM_T inum;

⌨️ 快捷键说明

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