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

📄 fatfs_meta.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** fatfs** The Sleuth Kit **** Content and meta data layer support for the FAT file system **** Brian Carrier [carrier <at> sleuthkit [dot] org]** Copyright (c) 2006-2008 Brian Carrier, Basis Technology.  All Rights reserved** Copyright (c) 2003-2005 Brian Carrier.  All rights reserved **** TASK** Copyright (c) 2002 Brian Carrier, @stake Inc.  All rights reserved****** This software is distributed under the Common Public License 1.0**** Unicode added with support from I.D.E.A.L. Technology Corp (Aug '05)***//** * \file fatfs_meta.c * Contains the internal TSK FAT file system code to handle metadata structures.  */#include "tsk_fs_i.h"#include "tsk_fatfs.h"/*  * Identify if the dentry is a valid 8.3 name * * returns 1 if it is, 0 if it does not */static uint8_tis_83_name(fatfs_dentry * de){    if (!de)        return 0;    /* The IS_NAME macro will fail if the value is 0x05, which is only     * valid in name[0], similarly with '.' */    if ((de->name[0] != FATFS_SLOT_E5) && (de->name[0] != '.') &&        (FATFS_IS_83_NAME(de->name[0]) == 0))        return 0;    // the name cannot start with 0x20    if (de->name[0] == 0x20)        return 0;    /* the second name field can only be . if the first one is a . */    if (de->name[1] == '.') {        if (de->name[0] != '.')            return 0;    }    else if (FATFS_IS_83_NAME(de->name[1]) == 0)        return 0;    if ((FATFS_IS_83_NAME(de->name[2]) == 0) ||        (FATFS_IS_83_NAME(de->name[3]) == 0) ||        (FATFS_IS_83_NAME(de->name[4]) == 0) ||        (FATFS_IS_83_NAME(de->name[5]) == 0) ||        (FATFS_IS_83_NAME(de->name[6]) == 0) ||        (FATFS_IS_83_NAME(de->name[7]) == 0) ||        (FATFS_IS_83_EXT(de->ext[0]) == 0) ||        (FATFS_IS_83_EXT(de->ext[1]) == 0) ||        (FATFS_IS_83_EXT(de->ext[2]) == 0))        return 0;    /* Ensure that if we get a "space", that the rest of the     * name is spaces.  This is not in the spec, but is how     * windows operates and serves as a good check to remove      * false positives.  We do not do this check for the      * volume label though. */    if ((de->attrib & FATFS_ATTR_VOLUME) != FATFS_ATTR_VOLUME) {        if (((de->name[1] == 0x20) && (de->name[2] != 0x20)) ||            ((de->name[2] == 0x20) && (de->name[3] != 0x20)) ||            ((de->name[3] == 0x20) && (de->name[4] != 0x20)) ||            ((de->name[4] == 0x20) && (de->name[5] != 0x20)) ||            ((de->name[5] == 0x20) && (de->name[6] != 0x20)) ||            ((de->name[6] == 0x20) && (de->name[7] != 0x20)) ||            ((de->ext[1] == 0x20) && (de->ext[2] != 0x20)))            return 0;    }    return 1;}/*** Convert the DOS time to the UNIX version** ** UNIX stores the time in seconds from 1970 in UTC** FAT dates are the actual date with the year relative to 1980** */static time_tdos2unixtime(uint16_t date, uint16_t time){    struct tm tm1;    time_t ret;    if (date == 0)        return 0;    memset(&tm1, 0, sizeof(struct tm));    tm1.tm_sec = ((time & FATFS_SEC_MASK) >> FATFS_SEC_SHIFT) * 2;    if ((tm1.tm_sec < 0) || (tm1.tm_sec > 60))        tm1.tm_sec = 0;    tm1.tm_min = ((time & FATFS_MIN_MASK) >> FATFS_MIN_SHIFT);    if ((tm1.tm_min < 0) || (tm1.tm_min > 59))        tm1.tm_min = 0;    tm1.tm_hour = ((time & FATFS_HOUR_MASK) >> FATFS_HOUR_SHIFT);    if ((tm1.tm_hour < 0) || (tm1.tm_hour > 23))        tm1.tm_hour = 0;    tm1.tm_mday = ((date & FATFS_DAY_MASK) >> FATFS_DAY_SHIFT);    if ((tm1.tm_mday < 1) || (tm1.tm_mday > 31))        tm1.tm_mday = 0;    tm1.tm_mon = ((date & FATFS_MON_MASK) >> FATFS_MON_SHIFT) - 1;    if ((tm1.tm_mon < 0) || (tm1.tm_mon > 11))        tm1.tm_mon = 0;    /* There is a limit to the year because the UNIX time value is     * a 32-bit value      * the maximum UNIX time is Tue Jan 19 03:14:07 2038     */    tm1.tm_year = ((date & FATFS_YEAR_MASK) >> FATFS_YEAR_SHIFT) + 80;    if ((tm1.tm_year < 0) || (tm1.tm_year > 137))        tm1.tm_year = 0;    /* set the daylight savings variable to -1 so that mktime() figures     * it out */    tm1.tm_isdst = -1;    ret = mktime(&tm1);    if (ret < 0) {        if (tsk_verbose)            tsk_fprintf(stderr,                "dos2unixtime: Error running mktime(): %d:%d:%d %d/%d/%d",                ((time & FATFS_HOUR_MASK) >> FATFS_HOUR_SHIFT),                ((time & FATFS_MIN_MASK) >> FATFS_MIN_SHIFT),                ((time & FATFS_SEC_MASK) >> FATFS_SEC_SHIFT) * 2,                ((date & FATFS_MON_MASK) >> FATFS_MON_SHIFT) - 1,                ((date & FATFS_DAY_MASK) >> FATFS_DAY_SHIFT),                ((date & FATFS_YEAR_MASK) >> FATFS_YEAR_SHIFT) + 80);        return 0;    }    return ret;}/*  * convert the attribute list in FAT to a UNIX mode  */static TSK_FS_META_TYPE_ENUMattr2type(uint16_t attr){    if (attr & FATFS_ATTR_DIRECTORY)        return TSK_FS_META_TYPE_DIR;    else        return TSK_FS_META_TYPE_REG;}static intattr2mode(uint16_t attr){    int mode;    /* every file is executable */    mode =        (TSK_FS_META_MODE_IXUSR | TSK_FS_META_MODE_IXGRP |        TSK_FS_META_MODE_IXOTH);    if ((attr & FATFS_ATTR_READONLY) == 0)        mode |=            (TSK_FS_META_MODE_IRUSR | TSK_FS_META_MODE_IRGRP |            TSK_FS_META_MODE_IROTH);    if ((attr & FATFS_ATTR_HIDDEN) == 0)        mode |=            (TSK_FS_META_MODE_IWUSR | TSK_FS_META_MODE_IWGRP |            TSK_FS_META_MODE_IWOTH);    return mode;}/**  * \internal * Copy the contents of a raw directry entry into a TSK_FS_INFO structure. * * @param fatfs File system that directory entry is from * @param fs_meta Generic inode structure to copy data into * @param in Directory entry to copy data from * @param sect Sector address where directory entry is from -- used * to determine allocation status. * @param inum Address of the inode. * * @returns 1 on error and 0 on success.  Errors should only occur for * Unicode conversion problems and when this occurs the name will be * NULL terminated (but with unknown contents).  * */TSK_RETVAL_ENUMfatfs_dinode_copy(FATFS_INFO * fatfs, TSK_FS_META * fs_meta,    fatfs_dentry * in, TSK_DADDR_T sect, TSK_INUM_T inum){    int retval;    int i;    TSK_FS_INFO *fs = (TSK_FS_INFO *) & fatfs->fs_info;    TSK_DADDR_T *addr_ptr;    if (fs_meta->content_len < FATFS_FILE_CONTENT_LEN) {        if ((fs_meta =                tsk_fs_meta_realloc(fs_meta,                    FATFS_FILE_CONTENT_LEN)) == NULL) {            return 1;        }    }    fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;    if (fs_meta->attr) {        tsk_fs_attrlist_markunused(fs_meta->attr);    }    fs_meta->mode = attr2mode(in->attrib);    fs_meta->type = attr2type(in->attrib);    fs_meta->addr = inum;    /* Use the allocation status of the sector to determine if the     * dentry is allocated or not */    retval = fatfs_is_sectalloc(fatfs, sect);    if (retval == -1) {        return TSK_ERR;    }    else if (retval == 1) {        fs_meta->flags = ((in->name[0] == FATFS_SLOT_DELETED) ?            TSK_FS_META_FLAG_UNALLOC : TSK_FS_META_FLAG_ALLOC);    }    else {        fs_meta->flags = TSK_FS_META_FLAG_UNALLOC;    }    /* Slot has not been used yet */    fs_meta->flags |= ((in->name[0] == FATFS_SLOT_EMPTY) ?        TSK_FS_META_FLAG_UNUSED : TSK_FS_META_FLAG_USED);    if ((in->attrib & FATFS_ATTR_LFN) == FATFS_ATTR_LFN) {        /* LFN entries don't have these values */        fs_meta->nlink = 0;        fs_meta->size = 0;        fs_meta->mtime = 0;        fs_meta->atime = 0;        fs_meta->ctime = 0;        fs_meta->crtime = 0;    }    else {        /* There is no notion of link in FAT, just deleted or not */        fs_meta->nlink = (in->name[0] == FATFS_SLOT_DELETED) ? 0 : 1;        fs_meta->size = (TSK_OFF_T) tsk_getu32(fs->endian, in->size);        /* If these are valid dates, then convert to a unix date format */        if (FATFS_ISDATE(tsk_getu16(fs->endian, in->wdate)))            fs_meta->mtime =                dos2unixtime(tsk_getu16(fs->endian, in->wdate),                tsk_getu16(fs->endian, in->wtime));        else            fs_meta->mtime = 0;        if (FATFS_ISDATE(tsk_getu16(fs->endian, in->adate)))            fs_meta->atime =                dos2unixtime(tsk_getu16(fs->endian, in->adate), 0);        else            fs_meta->atime = 0;        /* cdate is the creation date in FAT and there is no change,         * so we just put in into change and set create to 0.  The other         * front-end code knows how to handle it and display it         */        if (FATFS_ISDATE(tsk_getu16(fs->endian, in->cdate)))            fs_meta->crtime =                dos2unixtime(tsk_getu16(fs->endian, in->cdate),                tsk_getu16(fs->endian, in->ctime));        else            fs_meta->crtime = 0;        // FAT does not have a changed time        fs_meta->ctime = 0;    }    /* Values that do not exist in FAT */    fs_meta->uid = 0;    fs_meta->gid = 0;    fs_meta->seq = 0;    /* We will be copying a name, so allocate a structure */    if (fs_meta->name2 == NULL) {        if ((fs_meta->name2 = (TSK_FS_META_NAME_LIST *)                tsk_malloc(sizeof(TSK_FS_META_NAME_LIST))) == NULL)            return TSK_ERR;        fs_meta->name2->next = NULL;    }    /* If we have a LFN entry, then we need to convert the three     * parts of the name to UTF-8 and copy it into the name structure .     */    if ((in->attrib & FATFS_ATTR_LFN) == FATFS_ATTR_LFN) {        fatfs_dentry_lfn *lfn = (fatfs_dentry_lfn *) in;        /* Convert the first part of the name */        UTF8 *name8 = (UTF8 *) fs_meta->name2->name;        UTF16 *name16 = (UTF16 *) lfn->part1;        int retVal = tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &name16,            (UTF16 *) & lfn->part1[10],            &name8,            (UTF8 *) ((uintptr_t) fs_meta->name2->name +                sizeof(fs_meta->name2->name)),            TSKlenientConversion);        if (retVal != TSKconversionOK) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_UNICODE;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "fatfs_dinode_copy: Error converting FAT LFN (1) to UTF8: %d",                retVal);            *name8 = '\0';            return TSK_COR;        }        /* Convert the second part of the name */        name16 = (UTF16 *) lfn->part2;        retVal = tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &name16,            (UTF16 *) & lfn->part2[12],            &name8,            (UTF8 *) ((uintptr_t) fs_meta->name2->                name + sizeof(fs_meta->name2->name)),            TSKlenientConversion);        if (retVal != TSKconversionOK) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_UNICODE;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "fatfs_dinode_copy: Error converting FAT LFN (2) to UTF8: %d",                retVal);            *name8 = '\0';            return TSK_COR;        }        /* Convert the third part of the name */        name16 = (UTF16 *) lfn->part3;        retVal = tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &name16,            (UTF16 *) & lfn->part3[4],            &name8,            (UTF8 *) ((uintptr_t) fs_meta->name2->                name + sizeof(fs_meta->name2->name)),            TSKlenientConversion);        if (retVal != TSKconversionOK) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_UNICODE;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "fatfs_dinode_copy: Error converting FAT LFN (3) to UTF8: %d",

⌨️ 快捷键说明

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