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

📄 iso9660.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            // the first entry should have no name and is for the current directory            if ((i == 0) && (b_offs == sizeof(iso9660_dentry))) {                if (dentry->fi_len != 0) {                    // XXX                }                /* find how many more sectors are in the directory */                s_cnt =                    tsk_getu32(fs->endian,                    dentry->data_len_m) / ISO9660_SSIZE_B;                /* use the specified name instead of "." */                if (strlen(a_fn) > ISO9660_MAXNAMLEN_STD) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_ARG;                    snprintf(tsk_errstr, TSK_ERRSTR_L,                        "iso9660_load_inodes_dir: Name argument specified is too long");                    return -1;                }                strncpy(in_node->inode.fn, a_fn,                    ISO9660_MAXNAMLEN_STD + 1);                if (sizeof(iso9660_dentry) % 2)                    b_offs++;            }            else {                char *file_ver;                // the entry has a UTF-16 name                if (ctype == ISO9660_CTYPE_UTF16) {                    UTF16 *name16;                    UTF8 *name8;                    int retVal;                    name16 = (UTF16 *) & buf[b_offs];                    // the name is in UTF-16 BE -- convert to LE if needed                    if (fs->endian & TSK_LIT_ENDIAN) {                        int a;                        for (a = 0; a < dentry->fi_len / 2; a++) {                            name16[i] = ((name16[i] & 0xff) << 8) +                                ((name16[i] & 0xff00) >> 8);                        }                    }                    name8 = (UTF8 *) in_node->inode.fn;                    retVal =                        tsk_UTF16toUTF8(fs->endian,                        (const UTF16 **) &name16,                        (UTF16 *) & buf[b_offs + dentry->fi_len], &name8,                        (UTF8 *) ((uintptr_t) & in_node->inode.                            fn[ISO9660_MAXNAMLEN_STD]),                        TSKlenientConversion);                    if (retVal != TSKconversionOK) {                        if (tsk_verbose)                            tsk_fprintf(stderr,                                "iso9660_load_inodes_dir: Error converting Joliet name to UTF8: %d",                                retVal);                        in_node->inode.fn[0] = '\0';                    }                    *name8 = '\0';                }                else if (ctype == ISO9660_CTYPE_ASCII) {                    int readlen;                    readlen = dentry->fi_len;                    if (readlen > ISO9660_MAXNAMLEN_STD)                        readlen = ISO9660_MAXNAMLEN_STD;                    memcpy(in_node->inode.fn, &buf[b_offs], readlen);                    in_node->inode.fn[readlen] = '\0';                }                else {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_ARG;                    snprintf(tsk_errstr, TSK_ERRSTR_L,                        "Invalid ctype in iso9660_load_inodes_dir");                    return -1;                }                // the version is embedded in the name                file_ver = strchr(in_node->inode.fn, ';');                if (file_ver) {                    in_node->inode.version = atoi(file_ver + 1);                    *file_ver = '\0';                    file_ver = NULL;                }                // if no extension, remove the final '.'                if (in_node->inode.fn[strlen(in_node->inode.fn) - 1] ==                    '.')                    in_node->inode.fn[strlen(in_node->inode.fn) - 1] =                        '\0';                /* skip past padding byte */                b_offs += dentry->fi_len;                if (!(dentry->fi_len % 2)) {                    b_offs++;                }            }            // copy the raw dentry data into the node            memcpy(&(in_node->inode.dr), dentry, sizeof(iso9660_dentry));            in_node->inode.ea = NULL;            in_node->offset =                tsk_getu32(fs->endian, dentry->ext_loc_m) * fs->block_size;            in_node->ea_size = dentry->ext_len;            /* record size to make sure fifos show up as unique files */            in_node->size =                tsk_getu32(fs->endian, in_node->inode.dr.data_len_m);            in_node->inum = count++;            /* RockRidge data is located after the name.  See if it is there.  */            if ((int) (dentry->entry_len - sizeof(iso9660_dentry) -                    dentry->fi_len) > 1) {                int extra_bytes =                    dentry->entry_len - sizeof(iso9660_dentry) -                    dentry->fi_len;                // this takes care of the length adjustment that we already did                // on offs                if (extra_bytes % 2)                    extra_bytes--;                in_node->inode.rr =                    parse_susp(fs, &buf[b_offs], extra_bytes, NULL);                in_node->inode.susp_off = b_offs + s_offs;                in_node->inode.susp_len = extra_bytes;                if (in_node->inode.rr == NULL) {                    // return -1;                    // @@@ Verbose error                }                b_offs += extra_bytes;            }            else {                in_node->inode.susp_off = 0;                in_node->inode.susp_len = 0;            }            /* add inode to the list */            /* list not empty */            if (iso->in_list) {                iso9660_inode_node *tmp;                tmp = iso->in_list;                while ((tmp->next)                    && ((in_node->offset != tmp->offset)                        || (!in_node->size)                        || (!tmp->size)))                    tmp = tmp->next;                /* see if the file is already in list */                if ((in_node->offset == tmp->offset) && (in_node->size)                    && (tmp->size)) {                    if ((in_node->inode.rr) && (!tmp->inode.rr)) {                        tmp->inode.rr = in_node->inode.rr;                        in_node->inode.rr = NULL;                    }                    if (in_node->inode.rr)                        free(in_node->inode.rr);                    free(in_node);                    count--;                }                /* file wasn't in list, add it */                else {                    tmp->next = in_node;                    in_node->next = NULL;                }                /* list is empty */            }            else {                iso->in_list = in_node;                in_node->next = NULL;            }        }        s_offs += cnt1;    }    return count;}/** * Process the path table for a joliet secondary volume descriptor. * This will load each * of the directories in the table pointed to by he SVD. * * @param fs File system to process * @param svd Pointer to the secondary volume descriptor * @param count Current count of inodes * @returns updated count of inodes or -1 on error */static intiso9660_load_inodes_pt_joliet(TSK_FS_INFO * fs, iso9660_svd * svd,    int count){    TSK_OFF_T pt_offs;          /* offset of where we are in path table */    size_t pt_len;              /* bytes left in path table */    // get the location of the path table    pt_offs =        (TSK_OFF_T) (tsk_getu32(fs->endian,            svd->pt_loc_m) * fs->block_size);    pt_len = tsk_getu32(fs->endian, svd->pt_size_m);    while (pt_len > 0) {        char utf16_buf[ISO9660_MAXNAMLEN_JOL + 1];      // UTF-16 name from img        char utf8buf[2 * ISO9660_MAXNAMLEN_JOL + 1];    // UTF-8 version of name        int readlen;        TSK_OFF_T extent;       /* offset of extent for current directory */        path_table_rec dir;        int retVal;        ssize_t cnt;        UTF16 *name16;        UTF8 *name8;        // read the next entry        cnt = tsk_fs_read(fs, pt_offs, (char *) &dir, (int) sizeof(dir));        if (cnt != sizeof(dir)) {            if (cnt >= 0) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_READ;            }            snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso9660_load_inodes_pt");            return -1;        }        pt_len -= cnt;        pt_offs += (TSK_OFF_T) cnt;        readlen = dir.len_di;        if (dir.len_di > ISO9660_MAXNAMLEN_JOL)            readlen = ISO9660_MAXNAMLEN_JOL;        /* get UCS-2 filename for the entry */        cnt = tsk_fs_read(fs, pt_offs, (char *) utf16_buf, readlen);        if (cnt != dir.len_di) {            if (cnt >= 0) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_READ;            }            snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso_find_inodes");            return -1;        }        pt_len -= cnt;        pt_offs += (TSK_OFF_T) cnt;        // ISO stores UTF-16 in BE -- convert to local if we need to        if (fs->endian & TSK_LIT_ENDIAN) {            int i;            for (i = 0; i < cnt; i += 2) {                char t = utf16_buf[i];                utf16_buf[i] = utf16_buf[i + 1];                utf16_buf[i] = t;            }        }        name16 = (UTF16 *) utf16_buf;        name8 = (UTF8 *) utf8buf;        retVal = tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &name16,            (UTF16 *) ((uintptr_t) & utf16_buf[cnt + 1]), &name8,            (UTF8 *) ((uintptr_t) & utf8buf[2 * ISO9660_MAXNAMLEN_JOL]),            TSKlenientConversion);        if (retVal != TSKconversionOK) {            if (tsk_verbose)                tsk_fprintf(stderr,                    "fsstat: Error converting Joliet name to UTF8: %d",                    retVal);            utf8buf[0] = '\0';        }        *name8 = '\0';        /* padding byte is there if strlen(file name) is odd */        if (dir.len_di % 2) {            pt_len--;            pt_offs++;        }        extent =            (TSK_OFF_T) (tsk_getu32(fs->endian,                dir.ext_loc) * fs->block_size);        count =            iso9660_load_inodes_dir(fs, extent, count,            ISO9660_CTYPE_UTF16, utf8buf);        if (count == -1) {            return -1;        }    }    return count;}/** * Proces the path table and identify the directories that are listed.  The contents of each directory will also * be processed.  The result will be that the list of inodes in the image will be loaded in ISO_INFO. * * @param iso File system to analyze and store results in * @returns -1 on error or count of inodes found. */static intiso9660_load_inodes_pt(ISO_INFO * iso){    TSK_FS_INFO *fs = (TSK_FS_INFO *) & iso->fs_info;    int count = 0;    iso9660_svd_node *s;    iso9660_pvd_node *p;    char fn[ISO9660_MAXNAMLEN_STD + 1]; /* store current directory name */    path_table_rec dir;    TSK_OFF_T pt_offs;          /* offset of where we are in path table */    size_t pt_len;              /* bytes left in path table */    TSK_OFF_T extent;           /* offset of extent for current directory */    ssize_t cnt;    if (tsk_verbose)        tsk_fprintf(stderr, "iso9660_load_inodes_pt: iso: %lu\n",            (uintptr_t) iso);    /* initialize in case repeatedly called */    iso9660_inode_list_free(fs);    iso->in_list = NULL;    /* The secondary volume descriptor table will contain the     * longer / unicode files, so we process it first to give them     * a higher priority */    for (s = iso->svd; s != NULL; s = s->next) {        /* Check if this is Joliet -- there are three possible signatures */        if ((s->svd.esc_seq[0] == 0x25) && (s->svd.esc_seq[1] == 0x2F) &&            ((s->svd.esc_seq[2] == 0x40) || (s->svd.esc_seq[2] == 0x43)                || (s->svd.esc_seq[2] == 0x45))) {            count = iso9660_load_inodes_pt_joliet(fs, &(s->svd), count);            if (count == -1) {                return -1;            }        }    }    /* Now look for unique files in the primary descriptors */    for (p = iso->pvd; p != NULL; p = p->next) {        pt_offs =            (TSK_OFF_T) (tsk_getu32(fs->endian,                p->pvd.pt_loc_m) * fs->block_size);        pt_len = tsk_getu32(fs->endian, p->pvd.pt_size_m);        while (pt_len > 0) {            int readlen;            /* get next dir... */            cnt = tsk_fs_read(fs, pt_offs, (char *) &dir, sizeof(dir));            if (cnt != sizeof(dir)) {                if (cnt >= 0) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_READ;                }                snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso_find_inodes");                return -1;            }            pt_len -= cnt;            pt_offs += (TSK_OFF_T) cnt;            readlen = dir.len_di;            if (readlen > ISO9660_MAXNAMLEN_STD)                readlen = ISO9660_MAXNAMLEN_STD;            /* get directory name, this is the only chance */            cnt = tsk_fs_read(fs, pt_offs, fn, readlen);            if (cnt != readlen) {                if (cnt >= 0) {                    tsk_error_reset();                    tsk_errno = TSK_ERR_FS_READ;                }                snprintf(tsk_errstr2, TSK_ERRSTR_L, "iso_find_inodes");                return -1;            }            fn[cnt] = '\0';            pt_len -= cnt;            pt_offs += (TSK_OFF_T) cnt;            /* padding byte is there if strlen(file name) is odd */            if (dir.len_di % 2) {                pt_len--;                pt_offs++;            }            extent =                (TSK_OFF_T) (tsk_getu32(fs->endian,                    dir.ext_loc) * fs->block_size);            count =                iso9660_load_inodes_dir(fs, extent, count,                ISO9660_CTYPE_ASCII, fn);            if (count == -1) {                return -1;            }        }    }

⌨️ 快捷键说明

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