Beispiel #1
0
/**
 * \internal
 * Prints file system category data for an exFAT file system to a file 
 * handle. 
 *
 * @param [in] a_fs Generic file system info structure for the file system.
 * @param [in] a_hFile The file handle.
 * @return 0 on success, 1 otherwise, per TSK convention.
 */
static uint8_t
exfatfs_fsstat_fs_info(TSK_FS_INFO *a_fs, FILE *a_hFile)
{
    FATFS_INFO *fatfs = NULL;
    EXFATFS_MASTER_BOOT_REC *exfatbs = NULL;
    TSK_FS_FILE *fs_file = NULL;

    assert(a_fs != NULL);
    assert(a_hFile != NULL);

    fatfs = (FATFS_INFO*)a_fs;
    exfatbs = (EXFATFS_MASTER_BOOT_REC*)&(fatfs->boot_sector_buffer);

    if ((fs_file = tsk_fs_file_alloc(a_fs)) == NULL) {
        return FATFS_FAIL;
    }

    if ((fs_file->meta = tsk_fs_meta_alloc(FATFS_FILE_CONTENT_LEN)) == NULL) {
        return FATFS_FAIL;
    }

    tsk_fprintf(a_hFile, "FILE SYSTEM INFORMATION\n");
    tsk_fprintf(a_hFile, "--------------------------------------------\n");

    tsk_fprintf(a_hFile, "File System Type: exFAT\n");

    tsk_fprintf(a_hFile, "\nVolume Serial Number: %x%x-%x%x\n", 
        exfatbs->vol_serial_no[3], exfatbs->vol_serial_no[2], 
        exfatbs->vol_serial_no[1], exfatbs->vol_serial_no[0]);

    if (exfatfs_find_volume_label_dentry(fatfs, fs_file) == 0) {
        tsk_fprintf(a_hFile, "Volume Label (from root directory): %s\n", fs_file->meta->name2->name);
    }
    else {
        tsk_fprintf(a_hFile, "Volume Label:\n");
    }

    tsk_fprintf(a_hFile, "File System Name (from MBR): %s\n", exfatbs->fs_name);

    tsk_fprintf(a_hFile, "File System Revision: %x.%x\n", 
        exfatbs->fs_revision[1], exfatbs->fs_revision[0]);

    tsk_fprintf(a_hFile, "Partition Offset: %" PRIuDADDR "\n", 
        tsk_getu64(a_fs->endian, exfatbs->partition_offset));

    tsk_fprintf(a_hFile, "Number of FATs: %d\n", fatfs->numfat);

    tsk_fs_file_close(fs_file);

    return FATFS_OK;
}
Beispiel #2
0
/** \internal
 * Adds the fake metadata entry in the FS_DIR->fs_file struct for the orphan files directory
 *
 * @returns 1 on error
 */
static uint8_t
tsk_fs_dir_add_orphan_dir_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR * a_fs_dir)
{
    // populate the fake FS_FILE structure for the "Orphan Directory"
    if ((a_fs_dir->fs_file = tsk_fs_file_alloc(a_fs)) == NULL) {
        return 1;
    }

    if ((a_fs_dir->fs_file->meta =
            tsk_fs_meta_alloc(sizeof(TSK_DADDR_T))) == NULL) {
        return 1;
    }

    if (tsk_fs_dir_make_orphan_dir_meta(a_fs, a_fs_dir->fs_file->meta)) {
        return 1;
    }
    return 0;
}
Beispiel #3
0
/**
 * \internal
 * Searches an exFAT file system for its volume label directory entry, which 
 * should be in the root directory of the file system. If the entry is found, 
 * its metadata is copied into the TSK_FS_META object of a TSK_FS_FILE object.
 *
 * @param [in] a_fatfs Generic FAT file system info structure.
 * @param [out] a_fatfs Generic file system file structure.
 * @return 0 on success, 1 otherwise, per TSK convention.
 */
static uint8_t
exfatfs_find_volume_label_dentry(FATFS_INFO *a_fatfs, TSK_FS_FILE *a_fs_file)
{
    const char *func_name = "exfatfs_find_volume_label_dentry";
    TSK_FS_INFO *fs = (TSK_FS_INFO *)a_fatfs;
    TSK_DADDR_T current_sector = 0;
    TSK_DADDR_T last_sector_of_data_area = 0;
    char *sector_buf = NULL;
    ssize_t bytes_read = 0;
    TSK_INUM_T current_inum = 0;
    FATFS_DENTRY *dentry = NULL;
    uint64_t i = 0;

    assert(a_fatfs != NULL);
    assert(a_fs_file != NULL);

    tsk_error_reset();
    if (fatfs_ptr_arg_is_null(a_fatfs, "a_fatfs", func_name) ||
        fatfs_ptr_arg_is_null(a_fs_file, "a_fs_file", func_name)) {
        return FATFS_FAIL; 
    }

    /* Allocate or reset the TSK_FS_META object. */
    if (a_fs_file->meta == NULL) {
        if ((a_fs_file->meta =
                tsk_fs_meta_alloc(FATFS_FILE_CONTENT_LEN)) == NULL) {
            return FATFS_FAIL;
        }
    }
    else {
        tsk_fs_meta_reset(a_fs_file->meta);
    }

    /* Allocate a buffer for reading in sector-size chunks of the image. */
    if ((sector_buf = (char*)tsk_malloc(a_fatfs->ssize)) == NULL) {
        return FATFS_FAIL;
    }

    current_sector = a_fatfs->rootsect;
    last_sector_of_data_area = a_fatfs->firstdatasect + (a_fatfs->clustcnt * a_fatfs->csize) - 1;
    while (current_sector < last_sector_of_data_area) {
        int8_t sector_is_alloc = 0;

        /* Read in a sector from the root directory. The volume label
         * directory entry will probably be near the beginning of the 
         * directory, probably in the first sector. */
        bytes_read = tsk_fs_read_block(fs, current_sector, sector_buf, a_fatfs->ssize);
        if (bytes_read != a_fatfs->ssize) {
            if (bytes_read >= 0) {
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_FS_READ);
            }
            tsk_error_set_errstr2("%s: error reading sector: %" PRIuDADDR, func_name, current_sector);
            free(sector_buf);
            return FATFS_FAIL;
        }

        /* Get the allocation status of the sector (yes, it should be allocated). */
        sector_is_alloc = fatfs_is_sectalloc(a_fatfs, current_sector);
        if (sector_is_alloc == -1) {
            return FATFS_FAIL;
        }

        /* Get the inode address of the first directory entry of the sector. */
        current_inum = FATFS_SECT_2_INODE(a_fatfs, current_sector);

        /* Loop through the putative directory entries in the sector, 
         * until the volume label entry is found.  */
        for (i = 0; i < a_fatfs->ssize; i += sizeof(FATFS_DENTRY)) {
            dentry = (FATFS_DENTRY*)&(sector_buf[i]); 

            /* The type of the directory entry is encoded in the first byte 
             * of the entry. See EXFATFS_DIR_ENTRY_TYPE_ENUM. */ 
            if (exfatfs_get_enum_from_type(dentry->data[0]) == EXFATFS_DIR_ENTRY_TYPE_VOLUME_LABEL) {
                if (!exfatfs_is_vol_label_dentry(dentry, FATFS_DATA_UNIT_ALLOC_STATUS_UNKNOWN)) {
                    continue;
                }

                /* Found it, save it to the TSK_FS_META object of the 
                 * TSK_FS_FILE object and exit. */ 
                if (exfatfs_dinode_copy(a_fatfs, current_inum, dentry, 
                    sector_is_alloc, a_fs_file) == TSK_OK) {
                        return FATFS_OK;
                }
                else {
                    return FATFS_FAIL;
                }
            }
        }
    }

    free(sector_buf);
    return FATFS_OK;
}