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

📄 hfs.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (uni_len > 255) {        tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "hfs_read_thread_record: invalid string length (%" PRIu16 ")",            uni_len);        return 1;    }    if (hfs_checked_read_random(fs, (char *) thread->name.unicode,            uni_len * 2, addr + 10))        return 1;    return 0;}/** \internal * Read a catalog record into a local data structure.  This reads the * correct amount, depending on if it is a file or folder.  * @param hfs File system being analyzed * @param off Byte offset (in disk) of record  * @param record [out] Structure to read data into * @returns 1 on error */uint8_thfs_read_file_folder_record(HFS_INFO * hfs, TSK_OFF_T off,    hfs_file_folder * record){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);    memset(record, 0, sizeof(hfs_file_folder));    if (hfs_checked_read_random(fs, (char *) record, 2, off))        return 1;    if (tsk_getu16(fs->endian, record->file.rec_type) == HFS_FOLDER_RECORD) {        if (hfs_checked_read_random(fs, ((char *) record) + 2,                sizeof(hfs_folder) - 2, off + 2))            return 1;    }    else if (tsk_getu16(fs->endian,            record->file.rec_type) == HFS_FILE_RECORD) {        if (hfs_checked_read_random(fs, ((char *) record) + 2,                sizeof(hfs_file) - 2, off + 2))            return 1;    }    else {        tsk_errno = TSK_ERR_FS_GENFS;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "hfs_read_file_folder_record: unexpected record type %" PRIu16,            tsk_getu16(fs->endian, record->file.rec_type));        return 1;    }    return 0;}/** \internal * Lookup an entry in the catalog file and save it into the entry * data structure. * @param hfs File system being analyzed * @param inum Address (cnid) of file to open * @param entry [out] Structure to read data into * @returns 1 on error or not found, 0 on success. Check tsk_errno * to differentiate between error and not found. */uint8_thfs_catalog_lookup(HFS_INFO * hfs, TSK_INUM_T inum, HFS_ENTRY * entry){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);    hfs_cat_key key;            /* current catalog key */    uint32_t cnid;              /* catalog node ID of the entry (= inum) */    hfs_thread thread;          /* thread record */    hfs_file_folder record;     /* file/folder record */    TSK_OFF_T off;    char fname[HFS_MAXNAMLEN + 1];	uint32_t *temp_32ptr;    tsk_error_reset();    if (tsk_verbose)        tsk_fprintf(stderr,            "hfs_catalog_lookup: called for inum %" PRIuINUM "\n", inum);    /* first look up the thread record for the item we're searching for */    /* set up the thread record key */    cnid = (uint32_t) inum;    memset((char *) &key, 0, sizeof(hfs_cat_key));        temp_32ptr = (uint32_t *) (key.parent_cnid);    // @@@ Why is this needed, cnid is inum, which is local ordering...    // I think the goal is to put it back into BE ordering, but that seems to not work..    *temp_32ptr = tsk_getu32(fs->endian, (char *) &cnid);    /* look up the thread record */    off = hfs_find_catalog_record(hfs, &key);    if (off == 0)        return 1;    /* read the thread record */    if (hfs_read_thread_record(hfs, off, &thread))        return 1;    if (hfs_uni2ascii(fs, thread.name.unicode,            tsk_getu16(fs->endian, thread.name.length),            fname, HFS_MAXNAMLEN + 1))        return 1;    if (tsk_verbose)        fprintf(stderr,            "hfs_catalog_lookup: parent cnid %" PRIu32 " node name (%"            PRIu16 ") %s\n", tsk_getu32(fs->endian, thread.parent_cnid),            tsk_getu16(fs->endian, thread.name.length), fname);    /* now look up the actual file/folder record */    /* build key */    memset((char *) &key, 0, sizeof(hfs_cat_key));    memcpy(((char *) &key) + 2, ((char *) &thread) + 4,        sizeof(hfs_cat_key) - 2);    /* look up the record */    off = hfs_find_catalog_record(hfs, &key);    if (off == 0)        return 1;    /* read the record */    if (hfs_read_file_folder_record(hfs, off, &record))        return 1;    /* these memcpy can be gotten rid of, really */    if (tsk_getu16(fs->endian, record.file.rec_type) == HFS_FOLDER_RECORD) {        if (tsk_verbose)            fprintf(stderr,                "hfs_catalog_lookup: found folder record valence %" PRIu32                ", cnid %" PRIu32 "\n", tsk_getu32(fs->endian,                    record.folder.valence), tsk_getu32(fs->endian,                    record.folder.cnid));        memcpy((char *) &entry->cat, (char *) &record, sizeof(hfs_folder));    }    else if (tsk_getu16(fs->endian,            record.file.rec_type) == HFS_FILE_RECORD) {        if (tsk_verbose)            fprintf(stderr,                "hfs_catalog_lookup: found file record cnid %" PRIu32 "\n",                tsk_getu32(fs->endian, record.file.cnid));        memcpy((char *) &entry->cat, (char *) &record, sizeof(hfs_file));    }    /* other cases already caught by hfs_read_file_folder_record */    memcpy((char *) &entry->thread, (char *) &thread, sizeof(hfs_thread));    entry->flags |= TSK_FS_META_FLAG_ALLOC;     /// @@@ What about USED, etc.?    entry->inum = inum;    if (tsk_verbose)        tsk_fprintf(stderr, "hfs_catalog_lookup exited\n");    return 0;}/* get the catalog file header node and cache it.  This will be useful for * searching later * returns 0 on success, 1 on failure; sets up to error string 2 */static uint8_thfs_catalog_get_header(HFS_INFO * hfs){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);    int i;    hfs_btree_node node;    hfs_sb *sb = hfs->fs;    TSK_DADDR_T r_offs;    hfs_ext_desc *h;    tsk_error_reset();    if (tsk_verbose)        tsk_fprintf(stderr, "hfs_catalog_get_header: called\n");    /* already got it */    if (hfs->hdr)        return 0;    hfs->hdr = (hfs_btree_header_record *)        tsk_malloc(sizeof(hfs_btree_header_record));    if (hfs->hdr == NULL)        return 1;    /* find first extent with data in it */    i = 0;    h = sb->cat_file.extents;    while (!(tsk_getu32(fs->endian, h[i].blk_cnt)))        i++;    /* TODO this "find first extent" is unchecked */    r_offs = tsk_getu32(fs->endian, h[i].start_blk) * fs->block_size;    if (hfs_checked_read_random(fs, (char *) &node, sizeof(node), r_offs)) {        snprintf(tsk_errstr2, TSK_ERRSTR_L,            "hfs_catalog_get_header: reading catalog header node at %"            PRIuDADDR, r_offs);        return 1;    }    if (node.kind != HFS_BTREE_HEADER_NODE) {        tsk_errno = TSK_ERR_FS_GENFS;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "hfs_catalog_get_header: node zero at %" PRIuDADDR            " is incorrect type (%" PRIu8 ")", r_offs, node.kind);        return 1;    }    r_offs += sizeof(node);    /* get header node of btree */    if (hfs_checked_read_random(fs, (char *) hfs->hdr,            sizeof(hfs_btree_header_record), r_offs)) {        snprintf(tsk_errstr2, TSK_ERRSTR_L,            "hfs_catalog_get_header: reading catalog header at %"            PRIuDADDR, r_offs);        return 1;    }    return 0;}/* hfs_load_blockmap - This function will allocate a bitmap of blocks which * are allocated. */static inthfs_load_blockmap(HFS_INFO * hfs){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & (hfs->fs_info);    hfs_ext_desc *extents;    int i;    uint8_t *ptr;    uint32_t bytes_remaining;    if (tsk_verbose)        tsk_fprintf(stderr, "hfs_load_blockmap: called\n");    /* Note: the allocation file can be larger than the number of bytes       computed below. According to TN1150, all extra bits must be set to 0.       We avoid storing those empty bits; a consistency checker may want to       actually load the whole allocation file and check that these bits       are in fact empty. */    hfs->block_map_size =        (uint32_t) roundup(fs->block_count / 8, fs->block_size);    if ((hfs->block_map =            (uint8_t *) tsk_malloc(hfs->block_map_size)) == NULL)        return 1;    memset(hfs->block_map, 0, hfs->block_map_size);    extents =        hfs_ext_find_extent_record(hfs, HFS_ALLOCATION_FILE_ID,        hfs->fs->alloc_file.extents);    if (extents == NULL) {        tsk_fprintf(stderr,            "hfs_load_blockmap: failed to find extents for allocation file\n");        return 1;    }    i = 0;    ptr = hfs->block_map;    bytes_remaining = hfs->block_map_size;    while (bytes_remaining > 0) {        uint32_t blocks;        uint32_t bytes;        TSK_OFF_T offset;        blocks = tsk_getu32(fs->endian, extents[i].blk_cnt);        if (blocks == 0) {            tsk_fprintf(stderr,                "hfs_load_blockmap: ran out of data for allocation file\n");            free(extents);            return 1;        }		bytes = (bytes_remaining < blocks * fs->block_size) ? bytes_remaining : blocks * fs->block_size;        offset =            (TSK_OFF_T) tsk_getu32(fs->endian,            extents[i].start_blk) * fs->block_size;        if (hfs_checked_read_random(fs, (char *) ptr, bytes, offset)) {            free(extents);            return 1;        }        bytes_remaining -= bytes;        ptr += bytes;    }    free(extents);    return 0;}static TSK_FS_META_MODE_ENUMhfsmode2tskmode(uint16_t a_mode){    TSK_FS_META_MODE_ENUM mode = 0;    if (a_mode & HFS_IN_ISUID)        mode |= TSK_FS_META_MODE_ISUID;    if (a_mode & HFS_IN_ISGID)        mode |= TSK_FS_META_MODE_ISGID;    if (a_mode & HFS_IN_ISVTX)        mode |= TSK_FS_META_MODE_ISVTX;    if (a_mode & HFS_IN_IRUSR)        mode |= TSK_FS_META_MODE_IRUSR;    if (a_mode & HFS_IN_IWUSR)        mode |= TSK_FS_META_MODE_IWUSR;    if (a_mode & HFS_IN_IXUSR)        mode |= TSK_FS_META_MODE_IXUSR;    if (a_mode & HFS_IN_IRGRP)        mode |= TSK_FS_META_MODE_IRGRP;    if (a_mode & HFS_IN_IWGRP)        mode |= TSK_FS_META_MODE_IWGRP;    if (a_mode & HFS_IN_IXGRP)        mode |= TSK_FS_META_MODE_IXGRP;    if (a_mode & HFS_IN_IROTH)        mode |= TSK_FS_META_MODE_IROTH;    if (a_mode & HFS_IN_IWOTH)        mode |= TSK_FS_META_MODE_IWOTH;    if (a_mode & HFS_IN_IXOTH)        mode |= TSK_FS_META_MODE_IXOTH;    return mode;}static TSK_FS_META_TYPE_ENUMhfsmode2tskmetatype(uint16_t a_mode){    switch (a_mode & HFS_IN_IFMT) {    case HFS_IN_IFIFO:        return TSK_FS_META_TYPE_FIFO;    case HFS_IN_IFCHR:        return TSK_FS_META_TYPE_CHR;    case HFS_IN_IFDIR:        return TSK_FS_META_TYPE_DIR;    case HFS_IN_IFBLK:        return TSK_FS_META_TYPE_BLK;    case HFS_IN_IFREG:        return TSK_FS_META_TYPE_REG;    case HFS_IN_IFLNK:        return TSK_FS_META_TYPE_LNK;    case HFS_IN_IFSOCK:        return TSK_FS_META_TYPE_SOCK;    case HFS_IFWHT:        return TSK_FS_META_TYPE_WHT;    case HFS_IFXATTR:        return TSK_FS_META_TYPE_UNDEF;    default:        /* error */        return TSK_FS_META_TYPE_UNDEF;    }}/* * Copy the inode into the generic structure * Returns 1 on error. */uint8_thfs_dinode_copy(HFS_INFO * hfs, HFS_ENTRY * entry, TSK_FS_META * fs_inode){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & hfs->fs_info;    if (tsk_verbose)        tsk_fprintf(stderr, "hfs_dinode_copy: called\n");    fs_inode->attr_state =

⌨️ 快捷键说明

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