| 1 | /* @title: ISO9660 */ |
| 2 | #pragma once |
| 3 | #include <block/block.h> |
| 4 | #include <compiler.h> |
| 5 | #include <fs/vfs.h> |
| 6 | #include <stdint.h> |
| 7 | |
| 8 | struct iso9660_datetime { |
| 9 | uint8_t year; // since 1900 |
| 10 | uint8_t month; // 1–12 |
| 11 | uint8_t day; // 1–31 |
| 12 | uint8_t hour; // 0–23 |
| 13 | uint8_t minute; // 0–59 |
| 14 | uint8_t second; // 0–59 |
| 15 | int8_t gmt_offset; // in 15-minute intervals from GMT (-48 to +52) |
| 16 | } __packed; |
| 17 | |
| 18 | // Directory record (variable size, packed) |
| 19 | struct iso9660_dir_record { |
| 20 | uint8_t length; // total length of this record |
| 21 | uint8_t ext_attr_length; // extended attribute length |
| 22 | uint32_t extent_lba_le; // starting LBA (little endian) |
| 23 | uint32_t extent_lba_be; |
| 24 | uint32_t size_le; // file size in bytes (LE) |
| 25 | uint32_t size_be; |
| 26 | struct iso9660_datetime datetime; // date/time |
| 27 | uint8_t flags; // bit 1 = directory |
| 28 | uint8_t file_unit_size; |
| 29 | uint8_t interleave_gap_size; |
| 30 | uint16_t vol_seq_num_le; |
| 31 | uint16_t vol_seq_num_be; |
| 32 | uint8_t name_len; |
| 33 | char name[]; |
| 34 | } __packed; |
| 35 | |
| 36 | // Primary Volume Descriptor (fixed size, 2048 bytes) |
| 37 | struct iso9660_pvd { |
| 38 | uint8_t type; // must be 1 for PVD |
| 39 | char id[5]; // must be "CD001" |
| 40 | uint8_t version; // must be 1 |
| 41 | uint8_t unused1; |
| 42 | char system_id[32]; |
| 43 | char volume_id[32]; |
| 44 | uint8_t unused2[8]; |
| 45 | uint32_t volume_space_le; |
| 46 | uint32_t volume_space_be; |
| 47 | uint8_t unused3[32]; |
| 48 | uint16_t vol_set_size_le; |
| 49 | uint16_t vol_set_size_be; |
| 50 | uint16_t vol_seq_num_le; |
| 51 | uint16_t vol_seq_num_be; |
| 52 | uint16_t logical_block_size_le; |
| 53 | uint16_t logical_block_size_be; |
| 54 | uint32_t path_table_size_le; |
| 55 | uint32_t path_table_size_be; |
| 56 | uint32_t l_path_table_loc; |
| 57 | uint32_t opt_l_path_table_loc; |
| 58 | uint32_t m_path_table_loc; |
| 59 | uint32_t opt_m_path_table_loc; |
| 60 | struct iso9660_dir_record root_dir_record; |
| 61 | // couple more things - idrc about em so i'm leavin em out |
| 62 | } __packed; |
| 63 | |
| 64 | struct iso9660_fs { |
| 65 | struct partition *partition; |
| 66 | struct block_device *disk; |
| 67 | struct iso9660_pvd *pvd; |
| 68 | uint32_t root_lba; |
| 69 | uint32_t root_size; |
| 70 | uint32_t block_size; |
| 71 | }; |
| 72 | |
| 73 | struct vfs_node *iso9660_mount(struct partition *); |
| 74 | void iso9660_print(struct partition *); |
| 75 | struct iso9660_datetime iso9660_get_current_date(void); |
| 76 | |
| 77 | #define ISO9660_PVD_SECTOR 16 |
| 78 | #define ISO9660_SECTOR_SIZE 2048 |
| 79 | |