cleanup and bufixes

ntfs is weird so we can't trust the names in the index since sometimes they are wrong (?)
also the read function should return 0 for success and not read size...
This commit is contained in:
Itay Almog 2021-09-29 00:27:18 +03:00
parent 0cb083b3e4
commit 893020f303
2 changed files with 54 additions and 20 deletions

View File

@ -46,10 +46,6 @@ struct ntfs_file_handle {
// current open file/directory
uint8_t run_list[128];
bool has_resident;
uint8_t resident_index[256];
uint8_t attribute_list[256];
// info about the current file
uint32_t size_bytes;
};

View File

@ -60,6 +60,21 @@ struct file_record_attr_header_non_res {
uint16_t run_offset;
} __attribute__((packed));
struct file_record_attr_name {
uint64_t mft_parent_record;
uint64_t creation_time;
uint64_t altered_time;
uint64_t mft_changed_time;
uint64_t read_time;
uint64_t allocated_size;
uint64_t real_size;
uint32_t flags;
uint32_t reparse;
uint8_t name_length;
uint8_t name_type;
uint16_t name[];
} __attribute__((packed));
struct index_record {
char name[4];
uint16_t update_seq_offset;
@ -329,7 +344,7 @@ static bool ntfs_read_directory(struct ntfs_file_handle *handle, uint64_t mft_re
dir_buffer_size = dir_size;
// read the directory
if (ntfs_read(handle, dir_buffer, 0, dir_size) != (int)dir_size)
if (ntfs_read(handle, dir_buffer, 0, dir_size))
panic("NTFS: EOF before reading directory fully...");
return true;
@ -371,13 +386,10 @@ static void ntfs_read_root(struct ntfs_file_handle *handle) {
* Search for a file in the ntfs directory, assumes the directory has been read and is stored in
* the temp buffer
*/
static bool ntfs_find_file_in_directory(const char* filename, struct index_entry** out_entry) {
static bool ntfs_find_file_in_directory(struct ntfs_file_handle *handle, const char* filename, struct index_entry** out_entry) {
size_t dir_size = dir_buffer_size;
uint8_t *dir_ptr = dir_buffer;
(void)filename;
(void)out_entry;
// TODO: iterate resident record...
// get the size of the name we need to compare
@ -419,9 +431,25 @@ static bool ntfs_find_file_in_directory(const char* filename, struct index_entry
break;
if (filename_size == entry->name_length) {
// compare filename
for (int i = 0; i < entry->name_length; i++) {
if (filename[i] != entry->name[i]) {
// this name seem legit, need to get the real name from the mft
// sometimes it works to use the index name but sometimes it has
// invalid names for whatever reason that I can not understand, so
// just always take it from the mft file record
uint8_t file_record_buffer[MIN_FILE_RECORD_SIZE];
if (!ntfs_get_file_record(handle, entry->mft_record, file_record_buffer))
panic("NTFS: Failed to get file record");
uint8_t *name_attr = NULL;
if (!ntfs_get_file_record_attr(file_record_buffer, FR_ATTRIBUTE_NAME, &name_attr))
panic("NTFS: File record missing name attribute");
// get the offset to the actual info
struct file_record_attr_header_res *header = (struct file_record_attr_header_res *)name_attr;
struct file_record_attr_name *name = (struct file_record_attr_name *)(name_attr + header->info_offset);
// compare the name
for (int i = 0; i < name->name_length; i++) {
if (name->name[i] != filename[i]) {
goto next_entry;
}
}
@ -438,9 +466,16 @@ static bool ntfs_find_file_in_directory(const char* filename, struct index_entry
index_size -= entry->entry_size;
}
// next record
dir_ptr += index_record->index_entry_size;
dir_size -= index_record->index_entry_size;
// next record, need to do some rounding
index_size = index_record->index_entry_size;
if (index_size < 0x1000) {
index_size = 0x1000;
} else {
index_size = (index_size + 0x100) & 0xffffff00;
}
dir_ptr += index_size;
dir_size -= index_size;
}
return false;
@ -478,11 +513,13 @@ int ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *pat
struct index_entry* entry = NULL;
for (;;) {
// skip slash
current_path++;
while (*current_path == '\\' || *current_path == '/') {
current_path++;
}
// find the file in the directory
entry = NULL;
if (!ntfs_find_file_in_directory(current_path, &entry))
if (!ntfs_find_file_in_directory(ret, current_path, &entry))
return 1;
size_t filename_len = entry->name_length;
@ -532,10 +569,11 @@ int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t c
// get the runlist
uint8_t *runlist = file->run_list;
// TODO: remember the last read location so we can have faster sequential reads...
// we are going to go over the runlist until we get to the offset
// once we get to the offset we are going to continue going over
// the runlist while copying bytes
uint64_t wanted_to_read = count;
uint64_t bytes_per_cluster = file->bpb.sectors_per_cluster * file->bpb.bytes_per_sector;
do {
// get the next element from the runlist
@ -578,6 +616,6 @@ int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t c
}
} while(count);
// return how much we read...
return wanted_to_read - count;
// if we didn't read it all then we got a problem
return count != 0;
}