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

📄 ntfs.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        // figure out the needed offsets        cu_blkoffset = a_offset / fs->block_size;        if (cu_blkoffset) {            cu_blkoffset /= a_fs_attr->nrd.compsize;            cu_blkoffset *= a_fs_attr->nrd.compsize;        }        byteoffset = (size_t) (a_offset - cu_blkoffset * fs->block_size);        // cycle through the run until we find where we can start to process the clusters        for (data_run_cur = a_fs_attr->nrd.run;            (data_run_cur) && (buf_idx < a_len);            data_run_cur = data_run_cur->next) {            TSK_DADDR_T addr;            size_t a;            // See if this run contains the starting offset they requested            if (data_run_cur->offset + data_run_cur->len <                (TSK_DADDR_T) cu_blkoffset)                continue;            // seek to the start of where we want to read (we may need to read several runs)            if (data_run_cur->offset > (TSK_DADDR_T) cu_blkoffset)                a = 0;            else                a = (size_t) (cu_blkoffset - data_run_cur->offset);            addr = data_run_cur->addr;            // don't increment addr if it is 0 -- sparse            if (addr)                addr += a;            /* cycle through the relevant in the run */            for (; a < data_run_cur->len && buf_idx < a_len; a++) {                // queue up the addresses until we get a full unit                comp_unit[comp_unit_idx++] = addr;                // time to decompress (if queue is full or this is the last block)                if ((comp_unit_idx == a_fs_attr->nrd.compsize)                    || ((a == data_run_cur->len - 1)                        && (data_run_cur->next == NULL))) {                    size_t cpylen;                    // decompress the unit                    if (ntfs_proc_compunit(ntfs, &comp, comp_unit,                            comp_unit_idx)) {                        free(comp_unit);                        ntfs_uncompress_done(&comp);                        return -1;                    }                    // copy uncompressed data to the output buffer                    if (comp.uncomp_idx < byteoffset) {                        // @@ ERROR                        free(comp_unit);                        ntfs_uncompress_done(&comp);                        return -1;                    }                    else if (comp.uncomp_idx - byteoffset <                        a_len - buf_idx) {                        cpylen = comp.uncomp_idx - byteoffset;                    }                    else {                        cpylen = a_len - buf_idx;                    }                    memcpy(&a_buf[buf_idx], &comp.uncomp_buf[byteoffset],                        cpylen);                    // reset this in case we need to also read from the next run                     byteoffset = 0;                    buf_idx += cpylen;                    comp_unit_idx = 0;                }                /* If it is a sparse run, don't increment the addr so that                 * it remains 0 */                if (((data_run_cur->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) ==                        0)                    && ((data_run_cur->                            flags & TSK_FS_ATTR_RUN_FLAG_FILLER) == 0))                    addr++;            }        }        free(comp_unit);        ntfs_uncompress_done(&comp);        return (ssize_t) buf_idx;    }    else {        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "ntfs_file_read_special: called with non-special attribute: %x",            a_fs_attr->flags);        return -1;    }}/*  * Process an NTFS attribute sequence and load the data into data * structures.  * An attribute sequence is a linked list of the attributes in an MFT entry. * This is called by copy_inode and proc_attrlist. * * @param ntfs File system to analyze * @param fs_file Generic metadata structure to add the attribute info to * @param attrseq Start of the attribute sequence to analyze * @param len Length of the attribute sequence buffer * @returns Error code */static TSK_RETVAL_ENUMntfs_proc_attrseq(NTFS_INFO * ntfs,    TSK_FS_FILE * fs_file, ntfs_attr * attrseq, size_t len){    ntfs_attr *attr = attrseq;    const TSK_FS_ATTR *fs_attr_attrl = NULL;    char name[NTFS_MAXNAMLEN_UTF8 + 1];    TSK_FS_INFO *fs = (TSK_FS_INFO *) & ntfs->fs_info;    if (tsk_verbose)        tsk_fprintf(stderr,            "ntfs_proc_attrseq: Processing entry %"            PRIuINUM "\n", fs_file->meta->addr);    if (fs_file->meta->attr == NULL) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "Null attribute list in ntfs_proc_attrseq");        return TSK_ERR;    }    /* Cycle through the list of attributes */    for (; ((uintptr_t) attr >= (uintptr_t) attrseq)        && ((uintptr_t) attr <= ((uintptr_t) attrseq + len))        && (tsk_getu32(fs->endian, attr->len) > 0            && (tsk_getu32(fs->endian, attr->type) !=                0xffffffff));        attr =        (ntfs_attr *) ((uintptr_t) attr + tsk_getu32(fs->endian,                attr->len))) {        UTF16 *name16;        UTF8 *name8;        int retVal;        uint8_t isDefaultData = 0;        /* Get the type of this attribute */        uint32_t type = tsk_getu32(fs->endian, attr->type);        /* Copy the name and convert it to UTF8 */        if (attr->nlen) {            int i;            name8 = (UTF8 *) name;            name16 =                (UTF16 *) ((uintptr_t) attr + tsk_getu16(fs->endian,                    attr->name_off));            retVal =                tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &name16,                (UTF16 *) ((uintptr_t) name16 +                    attr->nlen * 2),                &name8,                (UTF8 *) ((uintptr_t) name8 +                    sizeof(name)), TSKlenientConversion);            if (retVal != TSKconversionOK) {                if (tsk_verbose)                    tsk_fprintf(stderr,                        "ntfs_proc_attrseq: Error converting NTFS attribute name to UTF8: %d %"                        PRIuINUM, retVal, fs_file->meta->addr);                *name = '\0';            }            /* Make sure it is NULL Terminated */            else if ((uintptr_t) name8 > (uintptr_t) name + sizeof(name))                name[sizeof(name)] = '\0';            else                *name8 = '\0';            /* Clean up name */            i = 0;            while (name[i] != '\0') {                if (TSK_IS_CNTRL(name[i]))                    name[i] = '^';                i++;            }        }        /* Call the unnamed $Data attribute, $Data */        else if (type == NTFS_ATYPE_DATA) {            name[0] = '$';            name[1] = 'D';            name[2] = 'a';            name[3] = 't';            name[4] = 'a';            name[5] = '\0';            isDefaultData = 1;  // save this so we know later in the loop        }        else {            name[0] = 'N';            name[1] = '/';            name[2] = 'A';            name[3] = '\0';        }        /* For resident attributes, we will copy the buffer into         * a TSK_FS_ATTR buffer, which is stored in the TSK_FS_META         * structure         */        if (attr->res == NTFS_MFT_RES) {            TSK_FS_ATTR *fs_attr;            if (tsk_verbose)                tsk_fprintf(stderr,                    "ntfs_proc_attrseq: Resident Attribute in %"                    PRIuINUM " Type: %" PRIu32 " Id: %"                    PRIu16 " Name: %s\n", ntfs->mnum,                    type, tsk_getu16(fs->endian, attr->id), name);            /* Validate the offset lengths */            if (((tsk_getu16(fs->endian,                            attr->c.r.soff) + (uintptr_t) attr) >                    ((uintptr_t) attrseq + len))                || ((tsk_getu16(fs->endian,                            attr->c.r.soff) + tsk_getu32(fs->endian,                            attr->c.r.ssize) + (uintptr_t) attr) >                    ((uintptr_t) attrseq + len))) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_CORRUPT;                snprintf(tsk_errstr, TSK_ERRSTR_L,                    "ntfs_attr_walk: Resident attribute %" PRIuINUM                    "-%" PRIu32 " starting offset and length too large",                    fs_file->meta->addr, type);                return TSK_COR;            }            // Get a free fs_attr structure             if ((fs_attr =                    tsk_fs_attrlist_getnew(fs_file->meta->attr,                        TSK_FS_ATTR_RES)) == NULL) {                strncat(tsk_errstr2, " - proc_attrseq",                    TSK_ERRSTR_L - strlen(tsk_errstr2));                return TSK_ERR;            }            // set the details in the fs_attr structure            if (tsk_fs_attr_set_str(fs_file, fs_attr, name, type,                    tsk_getu16(fs->endian, attr->id),                    (void *) ((uintptr_t) attr +                        tsk_getu16(fs->endian,                            attr->c.r.soff)), tsk_getu32(fs->endian,                        attr->c.r.ssize))) {                strncat(tsk_errstr2, " - proc_attrseq",                    TSK_ERRSTR_L - strlen(tsk_errstr2));                return TSK_ERR;            }            // set the meta size if we find the relevant attribute             if ((fs_file->meta->type == TSK_FS_META_TYPE_DIR)                && (type == NTFS_ATYPE_IDXROOT)) {                fs_file->meta->size =                    tsk_getu32(fs->endian, attr->c.r.ssize);            }            else if ((fs_file->meta->type == TSK_FS_META_TYPE_REG)                && (type == NTFS_ATYPE_DATA) && (isDefaultData)) {                fs_file->meta->size =                    tsk_getu32(fs->endian, attr->c.r.ssize);            }        }        /* For non-resident attributes, we will copy the runlist         * to the generic form and then save it in the TSK_FS_META->attr         * list         */        else {            TSK_FS_ATTR *fs_attr;            TSK_FS_ATTR_RUN *fs_attr_run;            uint8_t data_flag = 0;            uint16_t id = tsk_getu16(fs->endian, attr->id);            uint32_t compsize = 0;            TSK_RETVAL_ENUM retval;            if (tsk_verbose)                tsk_fprintf(stderr,                    "ntfs_proc_attrseq: Non-Resident Attribute in %"                    PRIuINUM " Type: %" PRIu32 " Id: %"                    PRIu16 " Name: %s  Start VCN: %"                    PRIu64 "\n", ntfs->mnum, type, id,                    name, tsk_getu64(fs->endian, attr->c.nr.start_vcn));            /* convert the run to generic form */            retval = ntfs_make_data_run(ntfs,                tsk_getu64(fs->endian, attr->c.nr.start_vcn),                (ntfs_runlist *) ((uintptr_t)                    attr + tsk_getu16(fs->endian,                        attr->c.nr.run_off)), &fs_attr_run, NULL);            if (retval != TSK_OK) {                strncat(tsk_errstr2, " - proc_attrseq",                    TSK_ERRSTR_L - strlen(tsk_errstr2));                return retval;            }            /* Determine the flags based on compression and stuff */            data_flag = 0;            if (tsk_getu16(fs->endian, attr->flags) & NTFS_ATTR_FLAG_COMP) {                data_flag |= TSK_FS_ATTR_COMP;                fs_file->meta->flags |= TSK_FS_META_FLAG_COMP;            }            if (tsk_getu16(fs->endian, attr->flags) & NTFS_ATTR_FLAG_ENC)                data_flag |= TSK_FS_ATTR_ENC;            if (tsk_getu16(fs->endian, attr->flags) & NTFS_ATTR_FLAG_SPAR)                data_flag |= TSK_FS_ATTR_SPARSE;            /* SPECIAL CASE              * We are in non-res section, so we know this             * isn't $STD_INFO and $FNAME             *             * When we are processing a non-base entry, we may             * find an attribute with an id of 0 and it is an             * extention of a previous run (i.e. non-zero start VCN)             *              * We will lookup if we already have such an attribute             * and get its ID             *             * We could also check for a start_vcn if this does             * not fix the problem             */            if (id == 0) {                int cnt, i;                // cycle through the attributes                cnt = tsk_fs_file_attr_getsize(fs_file);                for (i = 0; i < cnt; i++) {                    const TSK_FS_ATTR *fs_attr2 =                        tsk_fs_file_attr_get_idx(fs_file, i);                    if (!fs_attr2)                        continue;                    /* We found an attribute with the same name and type */                    if ((fs_attr2->type == type) &&                        (strcmp(fs_attr2->name, name) == 0)) {                        id = fs_attr2->id;                        if (tsk_verbose)                            tsk_fprintf(stderr,                                "ntfs_proc_attrseq: Updating id from 0 to %"                                PRIu16 "\n", id);                        break;                    }                }            }            /* the compression unit size is stored in the header             * it 

⌨️ 快捷键说明

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