| 1 | #include <stddef.h> |
| 2 | #include <stdint.h> |
| 3 | #include <fs/file.h> |
| 4 | #include <fs/fat32.h> |
| 5 | #include <fs/iso9660.h> |
| 6 | #include <lib/print.h> |
| 7 | #include <lib/misc.h> |
| 8 | #include <mm/pmm.h> |
| 9 | #include <lib/part.h> |
| 10 | #include <lib/libc.h> |
| 11 | #include <pxe/tftp.h> |
| 12 | |
| 13 | char *fs_get_label(struct volume *part) { |
| 14 | char *ret; |
| 15 | |
| 16 | if ((ret = fat32_get_label(part)) != NULL) { |
| 17 | return ret; |
| 18 | } |
| 19 | |
| 20 | return NULL; |
| 21 | } |
| 22 | |
| 23 | bool fs_get_guid(struct guid *guid, struct volume *part) { |
| 24 | (void)guid; (void)part; |
| 25 | |
| 26 | return false; |
| 27 | } |
| 28 | |
| 29 | bool case_insensitive_fopen = false; |
| 30 | |
| 31 | struct file_handle *fopen(struct volume *part, const char *filename) { |
| 32 | size_t filename_new_len = strlen(filename) + 2; |
| 33 | char *filename_new = ext_mem_alloc(filename_new_len); |
| 34 | |
| 35 | if (filename[0] != '/') { |
| 36 | filename_new[0] = '/'; |
| 37 | strcpy(&filename_new[1], filename); |
| 38 | } else { |
| 39 | strcpy(filename_new, filename); |
| 40 | } |
| 41 | |
| 42 | filename = filename_new; |
| 43 | |
| 44 | struct file_handle *ret; |
| 45 | |
| 46 | if (part->pxe) { |
| 47 | if ((ret = tftp_open(part, "", filename)) == NULL) { |
| 48 | goto err; |
| 49 | } |
| 50 | pmm_free(filename_new, filename_new_len); |
| 51 | return ret; |
| 52 | } |
| 53 | |
| 54 | if ((ret = iso9660_open(part, filename)) != NULL) { |
| 55 | goto success; |
| 56 | } |
| 57 | if ((ret = fat32_open(part, filename)) != NULL) { |
| 58 | goto success; |
| 59 | } |
| 60 | |
| 61 | err: |
| 62 | pmm_free(filename_new, filename_new_len); |
| 63 | return NULL; |
| 64 | |
| 65 | success: |
| 66 | ret->path = (char *)filename; |
| 67 | ret->path_len = filename_new_len; |
| 68 | |
| 69 | return ret; |
| 70 | } |
| 71 | |
| 72 | void fclose(struct file_handle *fd) { |
| 73 | if (fd->is_memfile) { |
| 74 | if (fd->readall == false) { |
| 75 | pmm_free(fd->fd, fd->size); |
| 76 | } |
| 77 | } else { |
| 78 | fd->close(fd); |
| 79 | } |
| 80 | pmm_free(fd->path, fd->path_len); |
| 81 | pmm_free(fd, sizeof(struct file_handle)); |
| 82 | } |
| 83 | |
| 84 | uint64_t fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) { |
| 85 | if (fd->is_memfile) { |
| 86 | if (fd->is_high_mem) { |
| 87 | panic(false, "fread: memfile resides above 4 GiB; caller must use load_addr_64 directly"); |
| 88 | } |
| 89 | if (loc >= fd->size || count > fd->size - loc) { |
| 90 | panic(false, "fread: attempted out of bounds read"); |
| 91 | } |
| 92 | memcpy(buf, fd->fd + loc, count); |
| 93 | return count; |
| 94 | } else { |
| 95 | return fd->read(fd, buf, loc, count); |
| 96 | } |
| 97 | } |