added support for resident files, this should pretty much complete a basic support for NTFS

This commit is contained in:
Itay Almog 2022-01-21 17:01:03 +02:00
parent 35d522d388
commit c74c36440a
2 changed files with 50 additions and 10 deletions

View File

@ -42,12 +42,18 @@ struct ntfs_file_handle {
uint64_t mft_offset;
uint8_t mft_run_list[256];
// the runlist, resident index and attribute list of the
// current open file/directory
// the runlist of the open file/directory
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[256];
// the resident data
uint8_t resident_data_size;
uint8_t resident_data[256];
// info about the current file
uint32_t size_bytes;
};

View File

@ -571,16 +571,33 @@ bool ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *pa
uint8_t *attr_ptr = NULL;
if (!ntfs_get_file_record_attr(file_record_buffer, FR_ATTRIBUTE_DATA, &attr_ptr))
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
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");
// mark that this has no resident data
ret->resident_index_size = 0;
// save the run list
memcpy(ret->run_list, (uint8_t *)attr + attr->run_offset, sizeof(ret->run_list));
// verify the attr and run list are in the buffer
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");
// 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;
@ -602,6 +619,23 @@ 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;
// 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...
// we are going to go over the runlist until we get to the offset