static int header_check_reg_nt(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) { const struct regf_file_header *header=(const struct regf_file_header*)buffer; if(le32(header->file_type) > 1) return 0; reset_file_recovery(file_recovery_new); file_recovery_new->min_filesize=0x1000; file_recovery_new->extension=file_hint_reg.extension; file_recovery_new->time=td_ntfs2utc(le64(header->modification_time)); return 1; }
/** * ntfs_td_list_entry * FIXME: Should we print errors as we go along? (AIA) */ static int ntfs_td_list_entry( struct ntfs_dir_struct *ls, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type) { int result = 0; char *filename; ntfs_inode *ni; ntfs_attr_search_ctx *ctx_si = NULL; file_info_t *new_file=NULL; /* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */ if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS) return 0; filename = (char *)calloc (1, MAX_PATH); if (!filename) { log_critical("ntfs_td_list_entry calloc failed\n"); return -1; } #ifdef HAVE_ICONV if (ntfs_ucstoutf8(ls->cd, name, name_len, &filename, MAX_PATH) < 0 && ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { log_error("Cannot represent filename in current locale.\n"); goto freefn; } #else if (ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) { log_error("Cannot represent filename in current locale.\n"); goto freefn; } #endif result = 0; /* These are successful */ if ((ls->dir_data->param & FLAG_LIST_SYSTEM)!=FLAG_LIST_SYSTEM && MREF(mref) < FILE_first_user && filename[0] == '$') /* Hide system file */ goto freefn; result = -1; /* Everything else is bad */ ni = ntfs_inode_open(ls->vol, mref); if (!ni) goto freefn; new_file=(file_info_t*)MALLOC(sizeof(*new_file)); new_file->status=0; new_file->st_ino=MREF(mref); new_file->st_uid=0; new_file->st_gid=0; ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec); if (ctx_si) { if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0) { const ATTR_RECORD *attr = ctx_si->attr; const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr + le16_to_cpu(attr->value_offset)); if(si) { new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time)); new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time)); new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time)); } } ntfs_attr_put_search_ctx(ctx_si); } { ATTR_RECORD *rec; int first=1; ntfs_attr_search_ctx *ctx = NULL; if (dt_type == NTFS_DT_DIR) { new_file->name=strdup(filename); new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO; new_file->st_size=0; td_list_add_tail(&new_file->list, &ls->dir_list->list); first=0; } ctx = ntfs_attr_get_search_ctx(ni, ni->mrec); /* A file has always an unnamed date stream and * may have named alternate data streams (ADS) */ while((rec = find_attribute(AT_DATA, ctx))) { const s64 filesize = ntfs_get_attribute_value_length(ctx->attr); if(rec->name_length && (ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS) continue; if(first==0) { const file_info_t *old_file=new_file; new_file=(file_info_t *)MALLOC(sizeof(*new_file)); memcpy(new_file, old_file, sizeof(*new_file)); } new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO; new_file->st_size=filesize; if (rec->name_length) { char *stream_name=NULL; new_file->status=FILE_STATUS_ADS; new_file->name = (char *)MALLOC(MAX_PATH); if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)), rec->name_length, &stream_name, 0) < 0) { log_error("ERROR: Cannot translate name into current locale.\n"); snprintf(new_file->name, MAX_PATH, "%s:???", filename); } else { snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name); } free(stream_name); } else { new_file->name=strdup(filename); } td_list_add_tail(&new_file->list, &ls->dir_list->list); first=0; } ntfs_attr_put_search_ctx(ctx); if(first) { free(new_file); } } result = 0; /* close the inode. */ ntfs_inode_close(ni); freefn: free (filename); return result; }
static int header_check_asf(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) { const struct asf_header_obj_s *hdr=(const struct asf_header_obj_s*)buffer; unsigned int i; const struct asf_file_prop_s *prop=(const struct asf_file_prop_s*)(hdr+1); uint64_t size=0; time_t time=0; const char *extension=file_hint_asf.extension; /* Header + File Properties + Stream Properties + Header Extension */ if(le64(hdr->object_size)<30 || le64(hdr->object_size)>buffer_size || le32(hdr->nbr_header_obj)<4) return 0; for(i=0; i<le32(hdr->nbr_header_obj) && (const unsigned char *)prop+0x28 < buffer + buffer_size; i++, prop=(const struct asf_file_prop_s *)((const char *)prop + le64(prop->object_size))) { // ASF_File_Properties_Object // 8CABDCA1-A947-11CF-8EE4-00C00C205365 // ASF_Stream_Properties_Object // B7DC0791-A9B7-11CF-8EE6-00C00C205365 static const unsigned char asf_file_prop_id[16]= { 0xa1, 0xdc, 0xab, 0x8c, 0x47, 0xa9, 0xcf, 0x11, 0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }; static const unsigned char asf_stream_prop_s[16]= { 0x91, 0x07, 0xdc, 0xb7, 0xb7, 0xa9, 0xcf, 0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }; if(le64(prop->object_size) < 0x18) { log_info("header_check_asf object_size too small %llu\n", (long long unsigned)le64(prop->object_size)); return 0; } if(memcmp(prop->object_id, asf_file_prop_id, sizeof(asf_file_prop_id))==0) { if(le64(prop->object_size) < 0x28) return 0; if(le64(prop->file_size) < sizeof(struct asf_header_obj_s) + sizeof(struct asf_file_prop_s)) return 0; size=le64(prop->file_size); time=td_ntfs2utc(le64(prop->file_date)); } else if(memcmp(prop->object_id, asf_stream_prop_s, sizeof(asf_stream_prop_s))==0) { const struct asf_stream_prop_s *stream=(const struct asf_stream_prop_s *)prop; const char wma[16]={ 0x40, 0x9e, 0x69, 0xf8, 0x4d, 0x5b, 0xcf, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }; const char wmv[16]={ 0xc0, 0xef, 0x19, 0xbc, 0x4d, 0x5b, 0xcf, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }; if(le64(prop->object_size) < 0x28) return 0; if(memcmp(stream->stream_type, wma, sizeof(wma))==0) extension="wma"; else if(memcmp(stream->stream_type, wmv, sizeof(wmv))==0) extension="wmv"; } if(le64(prop->object_size) > buffer_size) break; } reset_file_recovery(file_recovery_new); file_recovery_new->extension=extension; if(size > 0) { file_recovery_new->calculated_file_size=le64(size); file_recovery_new->data_check=&data_check_size; file_recovery_new->file_check=&file_check_size; } file_recovery_new->time=time; return 1; }