📄 fatfs.c
字号:
return 1; } if (tsk_verbose) tsk_fprintf(stderr, "fatfs_block_walk: Block Walking %" PRIuDADDR " to %" PRIuDADDR "\n", a_start_blk, a_end_blk); /* Sanity check on a_flags -- make sure at least one ALLOC is set */ if (((a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC) == 0) && ((a_flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC) == 0)) { a_flags |= (TSK_FS_BLOCK_WALK_FLAG_ALLOC | TSK_FS_BLOCK_WALK_FLAG_UNALLOC); } if (((a_flags & TSK_FS_BLOCK_WALK_FLAG_META) == 0) && ((a_flags & TSK_FS_BLOCK_WALK_FLAG_CONT) == 0)) { a_flags |= (TSK_FS_BLOCK_WALK_FLAG_CONT | TSK_FS_BLOCK_WALK_FLAG_META); } if ((fs_block = tsk_fs_block_alloc(fs)) == NULL) { return 1; } /* cycle through the sectors. We do the sectors before the first * cluster seperate from the data area */ addr = a_start_blk; /* Before the data area beings (FAT, root directory etc.) */ if ((a_start_blk < fatfs->firstclustsect) && (a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC)) { if (tsk_verbose) tsk_fprintf(stderr, "fatfs_block_walk: Walking non-data area (pre %" PRIuDADDR "\n", fatfs->firstclustsect); if ((data_buf = (char *) tsk_malloc(fs->block_size * 8)) == NULL) { tsk_fs_block_free(fs_block); return 1; } /* Read 8 sectors at a time to be faster */ for (; addr < fatfs->firstclustsect && addr <= a_end_blk;) { cnt = tsk_fs_read_block(fs, addr, data_buf, fs->block_size * 8); if (cnt != fs->block_size * 8) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_block_walk: pre-data area block: %" PRIuDADDR, addr); free(data_buf); tsk_fs_block_free(fs_block); return 1; } /* Process the sectors until we get to the clusters, * end of target, or end of buffer */ for (i = 0; i < 8 && (addr) <= a_end_blk && (addr) < fatfs->firstclustsect; i++, addr++) { int retval; myflags = TSK_FS_BLOCK_FLAG_ALLOC; /* stuff before the first data sector is the * FAT and boot sector */ if (addr < fatfs->firstdatasect) myflags |= TSK_FS_BLOCK_FLAG_META; /* This must be the root directory for FAT12/16 */ else myflags |= TSK_FS_BLOCK_FLAG_CONT; // test this sector (we already tested ALLOC) if ((myflags & TSK_FS_BLOCK_FLAG_META) && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_META))) continue; else if ((myflags & TSK_FS_BLOCK_FLAG_CONT) && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_CONT))) continue; tsk_fs_block_set(fs, fs_block, addr, myflags | TSK_FS_BLOCK_FLAG_RAW, &data_buf[i * fs->block_size]); retval = a_action(fs_block, a_ptr); if (retval == TSK_WALK_STOP) { free(data_buf); tsk_fs_block_free(fs_block); return 0; } else if (retval == TSK_WALK_ERROR) { free(data_buf); tsk_fs_block_free(fs_block); return 1; } } } free(data_buf); /* Was that it? */ if (addr >= a_end_blk) { tsk_fs_block_free(fs_block); return 0; } } /* Reset the first sector to the start of the data area if we did * not examine it - the next calculation will screw up otherwise */ else if (addr < fatfs->firstclustsect) { addr = fatfs->firstclustsect; } /* Now we read in the clusters in cluster-sized chunks, * sectors are too small */ /* Determine the base sector of the cluster where the first * sector is located */ addr = FATFS_CLUST_2_SECT(fatfs, (FATFS_SECT_2_CLUST(fatfs, addr))); if ((data_buf = tsk_malloc(fs->block_size * fatfs->csize)) == NULL) { tsk_fs_block_free(fs_block); return 1; } if (tsk_verbose) tsk_fprintf(stderr, "fatfs_block_walk: Walking data area blocks (%" PRIuDADDR " to %" PRIuDADDR ")\n", addr, a_end_blk); for (; addr <= a_end_blk; addr += fatfs->csize) { int retval; size_t read_size; /* Identify its allocation status */ retval = fatfs_is_sectalloc(fatfs, addr); if (retval == -1) { free(data_buf); tsk_fs_block_free(fs_block); return 1; } else if (retval == 1) { myflags = TSK_FS_BLOCK_FLAG_ALLOC; } else { myflags = TSK_FS_BLOCK_FLAG_UNALLOC; } /* At this point, there should be no more meta - just content */ myflags |= TSK_FS_BLOCK_FLAG_CONT; // test if we should call the callback with this one if ((myflags & TSK_FS_BLOCK_FLAG_CONT) && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_CONT))) continue; else if ((myflags & TSK_FS_BLOCK_FLAG_ALLOC) && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC))) continue; else if ((myflags & TSK_FS_BLOCK_FLAG_UNALLOC) && (!(a_flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC))) continue; /* The final cluster may not be full */ if (a_end_blk - addr + 1 < fatfs->csize) read_size = (size_t) (a_end_blk - addr + 1); else read_size = fatfs->csize; cnt = tsk_fs_read_block (fs, addr, data_buf, fs->block_size * read_size); if (cnt != fs->block_size * read_size) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_block_walk: block: %" PRIuDADDR, addr); free(data_buf); tsk_fs_block_free(fs_block); return 1; } /* go through each sector in the cluster */ for (i = 0; i < read_size; i++) { int retval; if (addr + i < a_start_blk) continue; else if (addr + i > a_end_blk) break; tsk_fs_block_set(fs, fs_block, addr + i, myflags | TSK_FS_BLOCK_FLAG_RAW, &data_buf[i * fs->block_size]); retval = a_action(fs_block, a_ptr); if (retval == TSK_WALK_STOP) { free(data_buf); tsk_fs_block_free(fs_block); return 0; } else if (retval == TSK_WALK_ERROR) { free(data_buf); tsk_fs_block_free(fs_block); return 1; } } } free(data_buf); tsk_fs_block_free(fs_block); return 0;}/* return 1 on error and 0 on success */static uint8_tfatfs_fscheck(TSK_FS_INFO * fs, FILE * hFile){ tsk_error_reset(); tsk_errno = TSK_ERR_FS_UNSUPFUNC; snprintf(tsk_errstr, TSK_ERRSTR_L, "fscheck not implemented for FAT yet"); return 1; /* Check that allocated dentries point to start of allcated cluster chain */ /* Size of file is consistent with cluster chain length */ /* Allocated cluster chains have a corresponding alloc dentry */ /* Non file dentries have no clusters */ /* Only one volume label */ /* Dump Bad Sector Addresses */ /* Dump unused sector addresses * Reserved area, end of FAT, end of Data Area */}/** * Print details about the file system to a file handle. * * @param fs File system to print details on * @param hFile File handle to print text to * * @returns 1 on error and 0 on success */static uint8_tfatfs_fsstat(TSK_FS_INFO * fs, FILE * hFile){ unsigned int i; int a; TSK_DADDR_T next, snext, sstart, send; FATFS_INFO *fatfs = (FATFS_INFO *) fs; fatfs_sb *sb = fatfs->sb; char *data_buf; fatfs_dentry *de; ssize_t cnt; // clean up any error messages that are lying around tsk_error_reset(); if ((data_buf = (char *) tsk_malloc(fatfs->ssize)) == NULL) { return 1; } /* Read the root directory sector so that we can get the volume * label from it */ cnt = tsk_fs_read_block(fs, fatfs->rootsect, data_buf, fatfs->ssize); if (cnt != fatfs->ssize) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_fsstat: root directory: %" PRIuDADDR, fatfs->rootsect); free(data_buf); return 1; } /* Find the dentry that is set as the volume label */ de = (fatfs_dentry *) data_buf; for (i = 0; i < fatfs->ssize; i += sizeof(*de)) { if (de->attrib == FATFS_ATTR_VOLUME) break; de++; } /* If we didn't find it, then reset de */ if (de->attrib != FATFS_ATTR_VOLUME) de = NULL; /* Print the general file system information */ tsk_fprintf(hFile, "FILE SYSTEM INFORMATION\n"); tsk_fprintf(hFile, "--------------------------------------------\n"); tsk_fprintf(hFile, "File System Type: FAT"); if (fs->ftype == TSK_FS_TYPE_FAT12) tsk_fprintf(hFile, "12\n"); else if (fs->ftype == TSK_FS_TYPE_FAT16) tsk_fprintf(hFile, "16\n"); else if (fs->ftype == TSK_FS_TYPE_FAT32) tsk_fprintf(hFile, "32\n"); else tsk_fprintf(hFile, "\n"); tsk_fprintf(hFile, "\nOEM Name: %c%c%c%c%c%c%c%c\n", sb->oemname[0], sb->oemname[1], sb->oemname[2], sb->oemname[3], sb->oemname[4], sb->oemname[5], sb->oemname[6], sb->oemname[7]); if (fatfs->fs_info.ftype != TSK_FS_TYPE_FAT32) { tsk_fprintf(hFile, "Volume ID: 0x%" PRIx32 "\n", tsk_getu32(fs->endian, sb->a.f16.vol_id)); tsk_fprintf(hFile, "Volume Label (Boot Sector): %c%c%c%c%c%c%c%c%c%c%c\n", sb->a.f16.vol_lab[0], sb->a.f16.vol_lab[1], sb->a.f16.vol_lab[2], sb->a.f16.vol_lab[3], sb->a.f16.vol_lab[4], sb->a.f16.vol_lab[5], sb->a.f16.vol_lab[6], sb->a.f16.vol_lab[7], sb->a.f16.vol_lab[8], sb->a.f16.vol_lab[9], sb->a.f16.vol_lab[10]); if ((de) && (de->name)) { tsk_fprintf(hFile, "Volume Label (Root Directory): %c%c%c%c%c%c%c%c%c%c%c\n", de->name[0], de->name[1], de->name[2], de->name[3], de->name[4], de->name[5], de->name[6], de->name[7], de->name[8], de->name[9], de->name[10]); } else { tsk_fprintf(hFile, "Volume Label (Root Directory):\n"); } tsk_fprintf(hFile, "File System Type Label: %c%c%c%c%c%c%c%c\n", sb->a.f16.fs_type[0], sb->a.f16.fs_type[1], sb->a.f16.fs_type[2], sb->a.f16.fs_type[3], sb->a.f16.fs_type[4], sb->a.f16.fs_type[5], sb->a.f16.fs_type[6], sb->a.f16.fs_type[7]); } else { char *fat_fsinfo_buf; fatfs_fsinfo *fat_info; if ((fat_fsinfo_buf = (char *) tsk_malloc(sizeof(fatfs_fsinfo))) == NULL) { free(data_buf); return 1; } tsk_fprintf(hFile, "Volume ID: 0x%" PRIx32 "\n", tsk_getu32(fs->endian, sb->a.f32.vol_id)); tsk_fprintf(hFile, "Volume Label (Boot Sector): %c%c%c%c%c%c%c%c%c%c%c\n", sb->a.f32.vol_lab[0], sb->a.f32.vol_lab[1], sb->a.f32.vol_lab[2], sb->a.f32.vol_lab[3], sb->a.f32.vol_lab[4], sb->a.f32.vol_lab[5], sb->a.f32.vol_lab[6], sb->a.f32.vol_lab[7], sb->a.f32.vol_lab[8], sb->a.f32.vol_lab[9], sb->a.f32.vol_lab[10]); if ((de) && (de->name)) { tsk_fprintf(hFile, "Volume Label (Root Directory): %c%c%c%c%c%c%c%c%c%c%c\n", de->name[0], de->name[1], de->name[2], de->name[3], de->name[4], de->name[5], de->name[6], de->name[7], de->name[8], de->name[9], de->name[10]); } else { tsk_fprintf(hFile, "Volume Label (Root Directory):\n"); } tsk_fprintf(hFile, "File System Type Label: %c%c%c%c%c%c%c%c\n", sb->a.f32.fs_type[0], sb->a.f32.fs_type[1], sb->a.f32.fs_type[2], sb->a.f32.fs_type[3], sb->a.f32.fs_type[4], sb->a.f32.fs_type[5], sb->a.f32.fs_type[6], sb->a.f32.fs_type[7]); /* Process the FS info */ if (tsk_getu16(fs->endian, sb->a.f32.fsinfo)) { cnt = tsk_fs_read_block(fs, (TSK_DADDR_T) tsk_getu16(fs->endian, sb->a.f32.fsinfo), fat_fsinfo_buf, sizeof(fatfs_fsinfo)); if (cnt != sizeof(fatfs_fsinfo)) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_fsstat: TSK_FS_TYPE_FAT32 FSINFO block: %" PRIuDADDR, (TSK_DADDR_T) tsk_getu16(fs->endian, sb->a.f32.fsinfo)); free(data_buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -