📄 fatfs_meta.c
字号:
retVal); *name8 = '\0'; return TSK_COR; } /* Make sure it is NULL Terminated */ if ((uintptr_t) name8 > (uintptr_t) fs_meta->name2->name + sizeof(fs_meta->name2->name)) fs_meta->name2->name[sizeof(fs_meta->name2->name) - 1] = '\0'; else *name8 = '\0'; } /* If the entry is for a volume label, then copy the name and * append a special label */ else if ((in->attrib & FATFS_ATTR_VOLUME) == FATFS_ATTR_VOLUME) { int a; i = 0; for (a = 0; a < 8; a++) { if ((in->name[a] != 0x00) && (in->name[a] != 0xff)) fs_meta->name2->name[i++] = in->name[a]; } for (a = 0; a < 3; a++) { if ((in->ext[a] != 0x00) && (in->ext[a] != 0xff)) fs_meta->name2->name[i++] = in->ext[a]; } fs_meta->name2->name[i] = '\0'; } /* If the entry is a normal short entry, then copy the name * and add the '.' for the extension */ else { for (i = 0; (i < 8) && (in->name[i] != 0) && (in->name[i] != ' '); i++) { if ((i == 0) && (in->name[0] == FATFS_SLOT_DELETED)) fs_meta->name2->name[0] = '_'; else if ((in->lowercase & FATFS_CASE_LOWER_BASE) && (in->name[i] >= 'A') && (in->name[i] <= 'Z')) fs_meta->name2->name[i] = in->name[i] + 32; else fs_meta->name2->name[i] = in->name[i]; } if ((in->ext[0]) && (in->ext[0] != ' ')) { int a; fs_meta->name2->name[i++] = '.'; for (a = 0; (a < 3) && (in->ext[a] != 0) && (in->ext[a] != ' '); a++, i++) { if ((in->lowercase & FATFS_CASE_LOWER_EXT) && (in->ext[a] >= 'A') && (in->ext[a] <= 'Z')) fs_meta->name2->name[i] = in->ext[a] + 32; else fs_meta->name2->name[i] = in->ext[a]; } } fs_meta->name2->name[i] = '\0'; } /* Clean up name to remove control characters */ i = 0; while (fs_meta->name2->name[i] != '\0') { if (TSK_IS_CNTRL(fs_meta->name2->name[i])) fs_meta->name2->name[i] = '^'; i++; } /* get the starting cluster */ addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr; if ((in->attrib & FATFS_ATTR_LFN) == FATFS_ATTR_LFN) { addr_ptr[0] = 0; } else { addr_ptr[0] = FATFS_DENTRY_CLUST(fs, in) & fatfs->mask; } /* FAT does not store a size for its directories so make one based * on the number of allocated sectors */ if ((in->attrib & FATFS_ATTR_DIRECTORY) && ((in->attrib & FATFS_ATTR_LFN) != FATFS_ATTR_LFN)) { if (fs_meta->flags & TSK_FS_META_FLAG_ALLOC) { TSK_LIST *list_seen = NULL; /* count the total number of clusters in this file */ TSK_DADDR_T clust = FATFS_DENTRY_CLUST(fs, in); int cnum = 0; while ((clust) && (0 == FATFS_ISEOF(clust, fatfs->mask))) { TSK_DADDR_T nxt; /* Make sure we do not get into an infinite loop */ if (tsk_list_find(list_seen, clust)) { if (tsk_verbose) tsk_fprintf(stderr, "Loop found while determining directory size\n"); break; } if (tsk_list_add(&list_seen, clust)) { tsk_list_free(list_seen); list_seen = NULL; return TSK_ERR; } cnum++; if (fatfs_getFAT(fatfs, clust, &nxt)) break; else clust = nxt; } tsk_list_free(list_seen); list_seen = NULL; fs_meta->size = (TSK_OFF_T) ((cnum * fatfs->csize) << fatfs->ssize_sh); } /* if the dir is unallocated, then assume 0 or cluster size * Ideally, we would have a smart algo here to do recovery * and look for dentries. However, we do not have that right * now and if we do not add this special check then it can * assume that an allocated file cluster chain belongs to the * directory */ else { // if the first cluster is allocated, then set size to be 0 if (fatfs_is_clustalloc(fatfs, FATFS_DENTRY_CLUST(fs, in)) == 1) fs_meta->size = 0; else fs_meta->size = fatfs->csize << fatfs->ssize_sh; } } return TSK_OK;}/** * \internal * Create an FS_INODE structure for the root directory. FAT does * not have a directory entry for the root directory, but this * function collects the needed data to make one. * * @param fatfs File system to analyze * @param fs_meta Inode structure to copy root directory information into. * @return 1 on error and 0 on success */uint8_tfatfs_make_root(FATFS_INFO * fatfs, TSK_FS_META * fs_meta){// TSK_FS_INFO *fs = (TSK_FS_INFO *) fatfs; TSK_DADDR_T *addr_ptr; fs_meta->type = (TSK_FS_META_TYPE_DIR); fs_meta->mode = 0; fs_meta->nlink = 1; fs_meta->addr = FATFS_ROOTINO; fs_meta->flags = (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_ALLOC); fs_meta->uid = fs_meta->gid = 0; fs_meta->mtime = fs_meta->atime = fs_meta->ctime = fs_meta->crtime = 0; if (fs_meta->name2 == NULL) { if ((fs_meta->name2 = (TSK_FS_META_NAME_LIST *) tsk_malloc(sizeof(TSK_FS_META_NAME_LIST))) == NULL) return 1; fs_meta->name2->next = NULL; } fs_meta->name2->name[0] = '\0'; addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr; /* TSK_FS_TYPE_FAT12 and TSK_FS_TYPE_FAT16 don't use the FAT for root directory, so * we will have to fake it. */ if (fatfs->fs_info.ftype != TSK_FS_TYPE_FAT32) { TSK_DADDR_T snum; /* Other code will have to check this as a special condition */ addr_ptr[0] = 1; /* difference between end of FAT and start of clusters */ snum = fatfs->firstclustsect - fatfs->firstdatasect; /* number of bytes */ fs_meta->size = snum << fatfs->ssize_sh; } else { /* Get the number of allocated clusters */ TSK_DADDR_T cnum; TSK_DADDR_T clust; TSK_LIST *list_seen = NULL; /* base cluster */ clust = FATFS_SECT_2_CLUST(fatfs, fatfs->rootsect); addr_ptr[0] = clust; cnum = 0; while ((clust) && (0 == FATFS_ISEOF(clust, FATFS_32_MASK))) { TSK_DADDR_T nxt; /* Make sure we do not get into an infinite loop */ if (tsk_list_find(list_seen, clust)) { if (tsk_verbose) tsk_fprintf(stderr, "Loop found while determining root directory size\n"); break; } if (tsk_list_add(&list_seen, clust)) { tsk_list_free(list_seen); list_seen = NULL; return 1; } cnum++; if (fatfs_getFAT(fatfs, clust, &nxt)) break; else clust = nxt; } tsk_list_free(list_seen); list_seen = NULL; fs_meta->size = (cnum * fatfs->csize) << fatfs->ssize_sh; } return 0;}/*** \internal * Create an FS_INODE structure for the master boot record. * * @param fatfs File system to analyze * @param fs_meta Inode structure to copy file information into. * @return 1 on error and 0 on success */uint8_tfatfs_make_mbr(FATFS_INFO * fatfs, TSK_FS_META * fs_meta){ TSK_DADDR_T *addr_ptr; TSK_FS_INFO *fs = (TSK_FS_INFO *) fatfs; fs_meta->type = TSK_FS_META_TYPE_VIRT; fs_meta->mode = 0; fs_meta->nlink = 1; fs_meta->addr = FATFS_MBRINO(fs); fs_meta->flags = (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_ALLOC); fs_meta->uid = fs_meta->gid = 0; fs_meta->mtime = fs_meta->atime = fs_meta->ctime = fs_meta->crtime = 0; if (fs_meta->name2 == NULL) { if ((fs_meta->name2 = (TSK_FS_META_NAME_LIST *) tsk_malloc(sizeof(TSK_FS_META_NAME_LIST))) == NULL) return 1; fs_meta->name2->next = NULL; } strncpy(fs_meta->name2->name, FATFS_MBRNAME, TSK_FS_META_NAME_LIST_NSIZE); addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr; addr_ptr[0] = 0; fs_meta->size = 512; return 0;}/*** \internal * Create an FS_INODE structure for the FAT tables. * * @param fatfs File system to analyze * @param a_which 1 or 2 to choose between defining FAT1 or FAT2 * @param fs_meta Inode structure to copy file information into. * @return 1 on error and 0 on success */uint8_tfatfs_make_fat(FATFS_INFO * fatfs, uint8_t a_which, TSK_FS_META * fs_meta){ TSK_FS_INFO *fs = (TSK_FS_INFO *) fatfs; TSK_DADDR_T *addr_ptr; fs_meta->type = TSK_FS_META_TYPE_VIRT; fs_meta->mode = 0; fs_meta->nlink = 1; fs_meta->flags = (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_ALLOC); fs_meta->uid = fs_meta->gid = 0; fs_meta->mtime = fs_meta->atime = fs_meta->ctime = fs_meta->crtime = 0; if (fs_meta->name2 == NULL) { if ((fs_meta->name2 = (TSK_FS_META_NAME_LIST *) tsk_malloc(sizeof(TSK_FS_META_NAME_LIST))) == NULL) return 1; fs_meta->name2->next = NULL; } if (a_which == 1) { fs_meta->addr = FATFS_FAT1INO(fs); strncpy(fs_meta->name2->name, FATFS_FAT1NAME, TSK_FS_META_NAME_LIST_NSIZE); addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr; addr_ptr[0] = fatfs->firstfatsect; } else if (a_which == 2) { fs_meta->addr = FATFS_FAT2INO(fs); strncpy(fs_meta->name2->name, FATFS_FAT2NAME, TSK_FS_META_NAME_LIST_NSIZE); addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr; addr_ptr[0] = fatfs->firstfatsect + fatfs->sectperfat; } else { ////XXXX } fs_meta->size = fatfs->sectperfat * fs->block_size; return 0;}/* * Is the pointed to buffer a directory entry buffer? * * Returns 1 if it is, 0 if not */uint8_tfatfs_isdentry(FATFS_INFO * fatfs, fatfs_dentry * de){ TSK_FS_INFO *fs = (TSK_FS_INFO *) & fatfs->fs_info; if (!de) return 0; /* LFN have their own checks, which are pretty weak since most * fields are UTF16 */ if ((de->attrib & FATFS_ATTR_LFN) == FATFS_ATTR_LFN) { fatfs_dentry_lfn *de_lfn = (fatfs_dentry_lfn *) de; if ((de_lfn->seq > (FATFS_LFN_SEQ_FIRST | 0x0f)) && (de_lfn->seq != FATFS_SLOT_DELETED)) return 0; return 1; } else { if (de->lowercase & ~(FATFS_CASE_LOWER_ALL)) return 0; else if (de->attrib & ~(FATFS_ATTR_ALL)) return 0; // verify we do not have too many flags set if (de->attrib & FATFS_ATTR_NORMAL) { if ((de->attrib & FATFS_ATTR_VOLUME) || (de->attrib & FATFS_ATTR_DIRECTORY)) return 0; } if (de->attrib & FATFS_ATTR_VOLUME) { if ((de->attrib & FATFS_ATTR_DIRECTORY) || (de->attrib & FATFS_ATTR_READONLY) || (de->attrib & FATFS_ATTR_ARCHIVE)) return 0; } /* The ctime, cdate, and adate fields are optional and * therefore 0 is a valid value */ if ((tsk_getu16(fs->endian, de->ctime) != 0) && (FATFS_ISTIME(tsk_getu16(fs->endian, de->ctime)) == 0)) return 0; else if ((tsk_getu16(fs->endian, de->wtime) != 0) && (FATFS_ISTIME(tsk_getu16(fs->endian, de->wtime)) == 0)) return 0; else if ((tsk_getu16(fs->endian, de->cdate) != 0) && (FATFS_ISDATE(tsk_getu16(fs->endian, de->cdate)) == 0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -