Merge pull request #149 from Itay2805/trunk

Finish NTFS implementation
This commit is contained in:
mint 2022-01-22 01:20:52 +01:00 committed by GitHub
commit b1a7c0d19f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 15 deletions

View File

@ -114,7 +114,7 @@ struct file_handle *fopen(struct volume *part, const char *filename) {
ret->fd = (void *)fd; ret->fd = (void *)fd;
ret->read = (void *)ntfs_read; ret->read = (void *)ntfs_read;
//ret->close = (void *)ntfs_close; ret->close = (void *)ntfs_close;
ret->size = fd->size_bytes; ret->size = fd->size_bytes;
return ret; return ret;

View File

@ -42,19 +42,26 @@ struct ntfs_file_handle {
uint64_t mft_offset; uint64_t mft_offset;
uint8_t mft_run_list[256]; uint8_t mft_run_list[256];
// the runlist, resident index and attribute list of the // the runlist of the open file/directory
// current open file/directory
uint8_t run_list[128]; uint8_t run_list[128];
// The resident index, only for directories,
// could be at the same time as a runlist
uint8_t resident_index_size; uint8_t resident_index_size;
uint8_t resident_index[256]; uint8_t resident_index[256];
// the resident data
uint8_t resident_data_size;
uint8_t resident_data[256];
// info about the current file // info about the current file
uint32_t size_bytes; uint32_t size_bytes;
}; };
int ntfs_check_signature(struct volume *part); int ntfs_check_signature(struct volume *part);
int ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *path); bool ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *path);
int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t count); int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t count);
void ntfs_close(struct ntfs_file_handle *file);
#endif #endif

View File

@ -514,7 +514,7 @@ static bool ntfs_find_file_in_directory(struct ntfs_file_handle *handle, const c
return false; return false;
} }
int ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *path) { bool ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *path) {
// save the part // save the part
ret->part = part; ret->part = part;
@ -553,7 +553,7 @@ int ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *pat
// find the file in the directory // find the file in the directory
entry = NULL; entry = NULL;
if (!ntfs_find_file_in_directory(ret, current_path, &entry)) if (!ntfs_find_file_in_directory(ret, current_path, &entry))
return 1; return false;
size_t filename_len = entry->name_length; size_t filename_len = entry->name_length;
@ -571,18 +571,35 @@ int ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *pat
uint8_t *attr_ptr = NULL; uint8_t *attr_ptr = NULL;
if (!ntfs_get_file_record_attr(file_record_buffer, FR_ATTRIBUTE_DATA, &attr_ptr)) if (!ntfs_get_file_record_attr(file_record_buffer, FR_ATTRIBUTE_DATA, &attr_ptr))
panic(false, "NTFS: File record missing DATA attribute"); panic(false, "NTFS: File record missing DATA attribute");
struct file_record_attr_header_non_res *attr = (struct file_record_attr_header_non_res *)attr_ptr; struct file_record_attr_header *attr_hdr = (struct file_record_attr_header *)attr_ptr;
if (attr_hdr->non_res_flag) {
// this is non-resident data
struct file_record_attr_header_non_res *attr = (struct file_record_attr_header_non_res *)attr_ptr;
// verify the attr and run list are in the buffer // mark that this has no resident data
if ((uint8_t *)attr + sizeof(*attr) > file_record_buffer + sizeof(file_record_buffer)) ret->resident_index_size = 0;
panic(false, "NTFS: File record attribute is outside of file record");
if ((uint8_t *)attr + attr->run_offset + 256 > file_record_buffer + sizeof(file_record_buffer))
panic(false, "NTFS: Run list is outside of file record");
// save the run list // verify the attr and run list are in the buffer
memcpy(ret->run_list, (uint8_t *)attr + attr->run_offset, sizeof(ret->run_list)); if ((uint8_t *)attr + sizeof(*attr) > file_record_buffer + sizeof(file_record_buffer))
panic(false, "NTFS: File record attribute is outside of file record");
if ((uint8_t *)attr + attr->run_offset + 256 > file_record_buffer + sizeof(file_record_buffer))
panic(false, "NTFS: Run list is outside of file record");
return 0; // save the run list
memcpy(ret->run_list, (uint8_t *)attr + attr->run_offset, sizeof(ret->run_list));
} else {
// this is resident data
struct file_record_attr_header_res *attr = (struct file_record_attr_header_res *)attr_ptr;
if (attr->info_length > sizeof(ret->resident_data))
panic(false, "NTFS: Resident data too big");
ret->resident_data_size = attr->info_length;
memcpy(ret->resident_data, attr + 1, attr->info_length);
}
return true;
} else { } else {
// read the directory // read the directory
@ -602,6 +619,23 @@ int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t c
// get the runlist // get the runlist
uint8_t *runlist = file->run_list; uint8_t *runlist = file->run_list;
// first try and handle resident data
if (file->resident_data_size != 0) {
// check bounds
if (loc > file->resident_data_size)
return 0;
// truncate the size
if (file->resident_data_size - loc < count) {
count = file->resident_data_size - loc;
}
// copy it
memcpy(buf, &file->resident_data[loc], count);
return count;
}
// TODO: remember the last read location so we can have faster sequential reads... // 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 // we are going to go over the runlist until we get to the offset
@ -652,3 +686,7 @@ int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t c
// if we didn't read it all then we got a problem // if we didn't read it all then we got a problem
return count != 0; return count != 0;
} }
void ntfs_close(struct ntfs_file_handle *file) {
pmm_free(file, sizeof(struct ntfs_file_handle));
}