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

📄 ntfs_dent.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            retval_tmp = ntfs_proc_idxentry(ntfs, fs_dir,                (fs_dir->fs_file->meta->                    flags & TSK_FS_META_FLAG_UNALLOC) ? 1 : 0, idxe,                list_len, tsk_getu32(a_fs->endian,                    idxelist->seqend_off) - tsk_getu32(a_fs->endian,                    idxelist->begin_off));            // stop if we get an error, record if we get corruption            if (retval_tmp == TSK_ERR) {                free(idxalloc);                return TSK_ERR;            }            else if (retval_tmp == TSK_COR) {                retval_final = TSK_COR;            }            /* reset the pointer to the next record */            idxrec_p = idxrec;        }                       /* end of cluster loop */        /* Process the final record */        if (idxrec_p) {            uint32_t list_len, rec_len;            /* Length from end of attribute to start of this */            rec_len =                (uint32_t) (idxalloc_len - (uintptr_t) idxrec_p -                (uintptr_t) idxalloc);            if (tsk_verbose)                tsk_fprintf(stderr,                    "ntfs_dir_open_meta: Processing final index record (len: %"                    PRIu32 ")\n", rec_len);            /* remove the update sequence */            if (ntfs_fix_idxrec(ntfs, idxrec_p, rec_len)) {                free(idxalloc);                return TSK_COR;            }            idxelist = &idxrec_p->list;            idxe = (ntfs_idxentry *) ((uintptr_t) idxelist +                tsk_getu32(a_fs->endian, idxelist->begin_off));            /* This is the length of the idx entries */            list_len =                (uint32_t) ((uintptr_t) idxalloc + idxalloc_len) -                (uintptr_t) idxe;            /* Verify the offset pointers */            if ((list_len > rec_len) ||                ((uintptr_t) idxelist +                    tsk_getu32(a_fs->endian, idxelist->seqend_off) >                    (uintptr_t) idxalloc + idxalloc_len)) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_INODE_COR;                snprintf(tsk_errstr, TSK_ERRSTR_L,                    "Error: Index list offsets are invalid on entry: %"                    PRIuINUM, fs_dir->fs_file->meta->addr);                free(idxalloc);                return TSK_COR;            }            /* process the list of index entries */            retval_tmp = ntfs_proc_idxentry(ntfs, fs_dir,                (fs_dir->fs_file->meta->                    flags & TSK_FS_META_FLAG_UNALLOC) ? 1 : 0, idxe,                list_len, tsk_getu32(a_fs->endian,                    idxelist->seqend_off) - tsk_getu32(a_fs->endian,                    idxelist->begin_off));            // stop if we get an error, record if we get corruption            if (retval_tmp == TSK_ERR) {                free(idxalloc);                return TSK_ERR;            }            else if (retval_tmp == TSK_COR) {                retval_final = TSK_COR;            }        }        free(idxalloc);    }    // add the orphan files that still point to this directory    data.parinode = a_addr;    data.fs_dir = fs_dir;    data.fs_name = tsk_fs_name_alloc(256, 0);    if (data.fs_name == NULL)        return TSK_ERR;    /* Walk unallocated MFT entries */    if (a_fs->inode_walk(a_fs, a_fs->first_inum, a_fs->last_inum,            TSK_FS_META_FLAG_UNALLOC, ntfs_par_act, &data)) {        tsk_fs_name_free(data.fs_name);        return TSK_ERR;    }    // if we are listing the root directory, add the Orphan directory entry    if (a_addr == a_fs->root_inum) {        if (tsk_fs_dir_make_orphan_dir_name(a_fs, data.fs_name)) {            tsk_fs_name_free(data.fs_name);            return TSK_ERR;        }        if (tsk_fs_dir_add(fs_dir, data.fs_name)) {            tsk_fs_name_free(data.fs_name);            return TSK_ERR;        }    }    tsk_fs_name_free(data.fs_name);    return retval_final;}/**************************************************************************** * FIND_FILE ROUTINES * */#define MAX_DEPTH   128#define DIR_STRSZ   4096typedef struct {    /* Recursive path stuff */    /* how deep in the directory tree are we */    unsigned int depth;    /* pointer in dirs string to where '/' is for given depth */    char *didx[MAX_DEPTH];    /* The current directory name string */    char dirs[DIR_STRSZ];} NTFS_DINFO;/*  * Looks up the parent inode described in fs_name.  * * fs_name was filled in by ntfs_find_file and will get the final path * added to it before action is called * * return 1 on error and 0 on success */static uint8_tntfs_find_file_rec(TSK_FS_INFO * fs, NTFS_DINFO * dinfo,    TSK_FS_FILE * fs_file, TSK_FS_META_NAME_LIST * fs_name_list,    TSK_FS_DIR_WALK_CB action, void *ptr){    TSK_FS_FILE *fs_file_par;    TSK_FS_META_NAME_LIST *fs_name_list_par;    uint8_t decrem = 0;    size_t len = 0, i;    char *begin = NULL;    int retval;    if (fs_name_list->par_inode < fs->first_inum ||        fs_name_list->par_inode > fs->last_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "invalid inode value: %" PRIuINUM "\n",            fs_name_list->par_inode);        return 1;    }    fs_file_par = tsk_fs_file_open_meta(fs, NULL, fs_name_list->par_inode);    if (fs_file_par == NULL) {        strncat(tsk_errstr2, " - ntfs_find_file_rec",            TSK_ERRSTR_L - strlen(tsk_errstr2));        return 1;    }    /*      * Orphan File     * This occurs when the file is deleted and either:     * - The parent is no longer a directory      * - The sequence number of the parent is no longer correct     */    if ((fs_file_par->meta->type != TSK_FS_META_TYPE_DIR)        || (fs_file_par->meta->seq != fs_name_list->par_seq)) {        char *str = TSK_FS_ORPHAN_STR;        len = strlen(str);        /* @@@ There should be a sanity check here to verify that the          * previous name was unallocated ... but how do I get it again?         */        if ((((uintptr_t) dinfo->didx[dinfo->depth - 1] - len) >=                (uintptr_t) & dinfo->dirs[0])            && (dinfo->depth < MAX_DEPTH)) {            begin = dinfo->didx[dinfo->depth] =                (char *) ((uintptr_t) dinfo->didx[dinfo->depth - 1] - len);            dinfo->depth++;            decrem = 1;            for (i = 0; i < len; i++)                begin[i] = str[i];        }        retval = action(fs_file, begin, ptr);        if (decrem)            dinfo->depth--;        tsk_fs_file_close(fs_file_par);        return (retval == TSK_WALK_ERROR) ? 1 : 0;    }    for (fs_name_list_par = fs_file_par->meta->name2;        fs_name_list_par != NULL;        fs_name_list_par = fs_name_list_par->next) {        len = strlen(fs_name_list_par->name);        /* do some length checks on the dir structure          * if we can't fit it then forget about it */        if ((((uintptr_t) dinfo->didx[dinfo->depth - 1] - len - 1) >=                (uintptr_t) & dinfo->dirs[0])            && (dinfo->depth < MAX_DEPTH)) {            begin = dinfo->didx[dinfo->depth] =                (char *) ((uintptr_t) dinfo->didx[dinfo->depth - 1] - len -                1);            dinfo->depth++;            decrem = 1;            *begin = '/';            for (i = 0; i < len; i++)                begin[i + 1] = fs_name_list_par->name[i];        }        else {            begin = dinfo->didx[dinfo->depth];            decrem = 0;        }        /* if we are at the root, then fill out the rest of fs_name with         * the full path and call the action          */        if (fs_name_list_par->par_inode == NTFS_ROOTINO) {            /* increase the path by one so that we do not pass the '/'             * if we do then the printed result will have '//' at              * the beginning             */            if (TSK_WALK_ERROR == action(fs_file,                    (const char *) ((uintptr_t) begin + 1), ptr)) {                tsk_fs_file_close(fs_file_par);                return 1;            }        }        /* otherwise, recurse some more */        else {            if (ntfs_find_file_rec(fs, dinfo, fs_file, fs_name_list_par,                    action, ptr)) {                tsk_fs_file_close(fs_file_par);                return 1;            }        }        /* if we incremented before, then decrement the depth now */        if (decrem)            dinfo->depth--;    }    tsk_fs_file_close(fs_file_par);    return 0;}/*  * this is a much faster way of doing it in NTFS  * * the inode that is passed in this case is the one to find the name * for * * This can not be called with dent_walk because the path * structure will get messed up! */uint8_tntfs_find_file(TSK_FS_INFO * fs, TSK_INUM_T inode_toid, uint32_t type_toid,    uint8_t type_used, uint16_t id_toid, uint8_t id_used,    TSK_FS_DIR_WALK_FLAG_ENUM dir_walk_flags, TSK_FS_DIR_WALK_CB action,    void *ptr){    TSK_FS_META_NAME_LIST *fs_name_list;    NTFS_INFO *ntfs = (NTFS_INFO *) fs;    char *attr = NULL;    NTFS_DINFO dinfo;    TSK_FS_FILE *fs_file;    /* sanity check */    if (inode_toid < fs->first_inum || inode_toid > fs->last_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "ntfs_find_file: invalid inode value: %" PRIuINUM "\n",            inode_toid);        return 1;    }    // open the file to ID    fs_file = tsk_fs_file_open_meta(fs, NULL, inode_toid);    if (fs_file == NULL) {        strncat(tsk_errstr2, " - ntfs_find_file",            TSK_ERRSTR_L - strlen(tsk_errstr2));        tsk_fs_file_close(fs_file);        return 1;    }    // see if its allocation status meets the callback needs    if ((fs_file->meta->flags & TSK_FS_META_FLAG_ALLOC)        && ((dir_walk_flags & TSK_FS_DIR_WALK_FLAG_ALLOC) == 0)) {        tsk_fs_file_close(fs_file);        return 1;    }    else if ((fs_file->meta->flags & TSK_FS_META_FLAG_UNALLOC)        && ((dir_walk_flags & TSK_FS_DIR_WALK_FLAG_UNALLOC) == 0)) {        tsk_fs_file_close(fs_file);        return 1;    }    /* Allocate a name and fill in some details  */    if ((fs_file->name =            tsk_fs_name_alloc(NTFS_MAXNAMLEN_UTF8, 0)) == NULL) {        return 1;    }    fs_file->name->meta_addr = inode_toid;    fs_file->name->meta_seq = 0;    fs_file->name->flags =        ((tsk_getu16(fs->endian,                ntfs->mft->                flags) & NTFS_MFT_INUSE) ? TSK_FS_NAME_FLAG_ALLOC :        TSK_FS_NAME_FLAG_UNALLOC);    memset(&dinfo, 0, sizeof(NTFS_DINFO));    /* in this function, we use the dinfo->dirs array in the opposite order.     * we set the end of it to NULL and then prepend the     * directories to it     *     * dinfo->didx[dinfo->depth] will point to where the current level started their     * dir name     */    dinfo.dirs[DIR_STRSZ - 2] = '/';    dinfo.dirs[DIR_STRSZ - 1] = '\0';    dinfo.didx[0] = &dinfo.dirs[DIR_STRSZ - 2];    dinfo.depth = 1;    /* Get the name for the attribute - if specified */    if (type_used) {        const TSK_FS_ATTR *fs_attr;        if (id_used)            fs_attr =                tsk_fs_attrlist_get_id(fs_file->meta->attr, type_toid,                id_toid);        else            fs_attr = tsk_fs_attrlist_get(fs_file->meta->attr, type_toid);        if (!fs_attr) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_INODE_COR;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "find_file: Type %" PRIu32 " Id %" PRIu16                " not found in MFT %" PRIuINUM "", type_toid, id_toid,                inode_toid);            tsk_fs_file_close(fs_file);            return 1;        }        /* only add the attribute name if it is the non-default data stream */        if (strcmp(fs_attr->name, "$Data") != 0)            attr = fs_attr->name;    }    /* loop through all the names it may have */    for (fs_name_list = fs_file->meta->name2; fs_name_list != NULL;        fs_name_list = fs_name_list->next) {        int retval;        /* Append on the attribute name, if it exists */        if (attr != NULL) {            snprintf(fs_file->name->name, fs_file->name->name_size,                "%s:%s", fs_name_list->name, attr);        }        else {            strncpy(fs_file->name->name, fs_name_list->name,                fs_file->name->name_size);        }        /* if this is in the root directory, then call back */        if (fs_name_list->par_inode == NTFS_ROOTINO) {            retval = action(fs_file, dinfo.didx[0], 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;            }        }        /* call the recursive function on the parent to get the full path */        else {            if (ntfs_find_file_rec(fs, &dinfo, fs_file, fs_name_list,                    action, ptr)) {                tsk_fs_file_close(fs_file);                return 1;            }        }    }                           /* end of name loop */    tsk_fs_file_close(fs_file);    return 0;}

⌨️ 快捷键说明

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