commit
b1a7c0d19f
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue