Advertisement
Guest User

Untitled

a guest
Sep 24th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.55 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <fs.h>
  3. #include <klib.h>
  4.  
  5. #define SECTOR_SIZE 2048
  6. #define FILE_TYPE 0
  7. #define DIR_TYPE 1
  8. #define FILE_FLAG_HIDDEN (1 << 0)
  9. #define FILE_FLAG_DIR (1 << 1)
  10. #define FILE_FLAG_ASSOCIATED (1 << 2)
  11. #define FILE_FLAG_XATTR_FORMAT (1 << 3)
  12. #define FILE_FLAG_XATTR_PERMS (1 << 4)
  13. #define FILE_FLAG_LARGE (1 << 7)
  14. #define PATH_MAX 4096
  15.  
  16. struct int16_LSB_MSB_t {
  17.     uint16_t little;
  18.     uint16_t big;
  19. }__attribute((packed));
  20.  
  21. struct int32_LSB_MSB_t {
  22.     uint32_t little;
  23.     uint32_t big;
  24. }__attribute__((packed));
  25.  
  26. struct dir_date_time_t {
  27.     uint8_t years;
  28.     uint8_t month;
  29.     uint8_t day;
  30.     uint8_t hour;
  31.     uint8_t minute;
  32.     uint8_t second;
  33.     uint8_t gmt_offset;
  34. }__attribute((packed));
  35.  
  36. struct dec_datetime {
  37.     char year[4];
  38.     char month[2];
  39.     char day[2];
  40.     char hour[2];
  41.     char minute[2];
  42.     char second[2];
  43.     char hundreth_second[2];
  44.     uint8_t gmt_offset;
  45. }__attribute((packed));
  46.  
  47. struct directory_entry_t {
  48.     uint8_t length;
  49.     uint8_t xattr_length;
  50.     struct int32_LSB_MSB_t extent_location;
  51.     struct int32_LSB_MSB_t extent_length;
  52.     struct dir_date_time_t date;
  53.     uint8_t flags;
  54.     uint8_t unit_size;
  55.     uint8_t interleave_size;
  56.     struct int16_LSB_MSB_t volume_sequence_number;
  57.     uint8_t name_length;
  58.     char name[];
  59. }__attribute((packed));
  60.  
  61. struct descriptor_header_t {
  62.     uint8_t type;
  63.     char standard_identifier[5];
  64.     uint8_t version;
  65. }__attribute__((packed));
  66.  
  67. struct primary_descriptor_t {
  68.     struct descriptor_header_t header;
  69.     uint8_t unused1;
  70.     char system_identifier[32];
  71.     char volume_identifier[32];
  72.     uint8_t unused2[8];
  73.     struct int32_LSB_MSB_t volume_space_size;
  74.     uint8_t unused3[32];
  75.     struct int16_LSB_MSB_t volume_set_size;
  76.     struct int16_LSB_MSB_t volume_sequence_number;
  77.     struct int16_LSB_MSB_t logical_block_size;
  78.     struct int32_LSB_MSB_t path_table_size;
  79.     uint32_t l_path_table_location;
  80.     uint32_t optional_l_path_table_location;
  81.     uint32_t m_path_table_location;
  82.     uint32_t optional_m_path_table_location;
  83.     struct directory_entry_t root_entry;
  84.     char volume_set_name[128];
  85.     char volume_publisher_name[128];
  86.     char data_preparer_name[128];
  87.     char application_name[128];
  88.     char copyright_name[38];
  89.     char abstract_name[36];
  90.     char bibliographic_name[37];
  91.     struct dec_datetime creation_date;
  92.     struct dec_datetime modification_date;
  93.     struct dec_datetime expiration_date;
  94.     struct dec_datetime effective_date;
  95.     uint8_t file_struct_version;
  96.     uint8_t unused4[513];
  97.     uint8_t reserved[653];
  98. }__attribute__((packed));
  99.  
  100. struct path_result_t {
  101.     struct directory_entry_t target;
  102.     struct directory_entry_t parent;
  103.     int failure;
  104.     int not_found;
  105. };
  106.  
  107. struct directory_result_t {
  108.     struct directory_entry_t *entries;
  109.     int num_entries;
  110.     int failure;
  111. };
  112.  
  113. struct mount_t {
  114.     char name[128];
  115.     int device;
  116.     uint32_t num_blocks;
  117.     uint16_t block_size;
  118.     uint32_t path_table_size;
  119.     uint32_t path_table_loc;
  120.     struct directory_entry_t root_entry;
  121. };
  122.  
  123. struct handle_t {
  124.     int free;
  125.     int mount;
  126.     int flags;
  127.     int mode;
  128.     long ptr;
  129.     long begin;
  130.     long end;
  131.     struct path_result_t path_res;
  132.     char path[PATH_MAX];
  133. };
  134.  
  135. int handle_i = 0;
  136. struct handle_t *handles;
  137.  
  138. int mount_i = 0;
  139. struct mount_t *mounts;
  140.  
  141. static uint8_t rd_byte(int handle, uint64_t location) {
  142.     uint8_t buf[1];
  143.     lseek(handle, location, SEEK_SET);
  144.     read(handle, buf, 1);
  145.     return buf[0];
  146. }
  147.  
  148. static int next_sector(int location) {
  149.     return (location % SECTOR_SIZE);
  150. }
  151.  
  152. static struct directory_result_t load_dir(struct mount_t *mount,
  153.       struct directory_entry_t *dir) {
  154.     struct directory_result_t result;
  155.     if (!(dir->flags & FILE_FLAG_DIR)) {
  156.       result.failure = 1;
  157.       return result;
  158.     }
  159.     result.entries = kalloc(dir->extent_length.little);
  160.  
  161.     size_t pos = 0;
  162.     int count = 0;
  163.     while (pos < dir->extent_length.little) {
  164.         uint8_t length = rd_byte(mount->device,
  165.                 (dir->extent_location.little * SECTOR_SIZE) + pos);
  166.         if (length == 0) {
  167.             /* the end of the sector is padded */
  168.             int offset = next_sector((dir->extent_location.little * SECTOR_SIZE)
  169.                     + pos);
  170.             pos += offset;
  171.             continue;
  172.         }
  173.  
  174.         lseek(mount->device, (dir->extent_location.little * SECTOR_SIZE) + pos,
  175.                 SEEK_SET);
  176.         read(mount->device, &result.entries[pos], length);
  177.         count++;
  178.         pos += length;
  179.     }
  180.     result.num_entries = count;
  181.     return result;
  182. }
  183.  
  184. static int create_handle(struct handle_t handle) {
  185.     for (int i = 0; i < handle_i; i++) {
  186.         if (handles[i].free) {
  187.             handles[i] = handle;
  188.             return i;
  189.         }
  190.     }
  191.     int handle_n = 0;
  192.     handles = krealloc(handles, (handle_i + 1) * sizeof(struct handle_t));
  193.     handle_n = handle_i++;
  194.     handles[handle_n] = handle;
  195.     return handle_n;
  196. }
  197.  
  198. static struct path_result_t resolve_path(struct mount_t *mount,
  199.         const char *path, int type) {
  200.     kprint(KPRN_DBG, "resolve_path()");
  201.     struct path_result_t result = {0};
  202.    
  203.     if (*path == '/') path++;
  204.  
  205.     struct directory_entry_t entry = {0};
  206.     struct directory_result_t current_dir = load_dir(mount, &mount->root_entry);
  207.     do {
  208.         kprint(KPRN_DBG, "resolve_path loop entry");
  209.         const char *seg = path;
  210.         path = kstrchrnul(path, '/');
  211.         size_t seg_length = path - seg;
  212.  
  213.         if (result.target.extent_location.little)
  214.             current_dir = load_dir(mount, &result.target);
  215.  
  216.         int found = 0;
  217.         int i = 0;
  218.         int pos = 0;
  219.         while (i < current_dir.num_entries) {
  220.             entry = current_dir.entries[pos];
  221.             kprint(KPRN_DBG, "%U", entry.name_length);
  222.             for (int i = 0; i < entry.name_length; i++)
  223.                 kprint(KPRN_DBG, "%x", entry.name[i]);
  224.             if (seg_length > entry.name_length)
  225.                 goto out;
  226.             if (kstrncmp(seg, entry.name, seg_length) != 0)
  227.                 goto out;
  228.             if (entry.name_length > seg_length && entry.name[seg_length]
  229.                     != ';')
  230.                 goto out;
  231.             found = 1;
  232.             break;
  233. out:
  234.             kprint(KPRN_DBG, "we left...");
  235.             i++;
  236.             pos += entry.length;
  237.         }
  238.  
  239.         if (!found) {
  240.             result.not_found = 1;
  241.             return result;
  242.         }
  243.         kprint(KPRN_DBG, "success!!");
  244.         result.parent = result.target;
  245.         result.target = entry;
  246.     } while(*path);
  247.  
  248.     return result;
  249. }
  250.  
  251. static int iso9660_open(const char *path, int flags, int mode, int mount) {
  252.     struct path_result_t result = resolve_path(&mounts[mount], path,
  253.             FILE_TYPE);
  254.    
  255.     if (result.failure || result.not_found)
  256.         return -1;
  257.  
  258.     struct handle_t handle = {0};
  259.     kstrcpy(handle.path, path);
  260.     handle.path_res = result;
  261.     handle.flags = flags;
  262.     handle.mode = mode;
  263.     handle.mount = mount;
  264.     handle.end = result.target.extent_length.little;
  265.     if (flags & O_APPEND) {
  266.         handle.begin = handle.end;
  267.         handle.ptr = handle.end;
  268.     } else {
  269.         handle.begin = 0;
  270.         handle.ptr = 0;
  271.     }
  272.     return create_handle(handle);
  273. }
  274.  
  275. static int iso9660_mount(const char *source) {
  276.     int device = open(source, O_RDONLY, 0);
  277.  
  278.     uint8_t type = rd_byte(device, 0x10 * SECTOR_SIZE);
  279.     if (type != 0x1) {
  280.         kprint(KPRN_ERR, "iso9660: cannot find primary volume descriptor!");
  281.         close(device);
  282.         return -1;
  283.     }
  284.  
  285.     struct primary_descriptor_t primary_descriptor;
  286.     lseek(device, 0x10 * SECTOR_SIZE, SEEK_SET);
  287.     read(device, &primary_descriptor, sizeof(struct primary_descriptor_t));
  288.  
  289.     mounts = krealloc(mounts, (mount_i + 1) * sizeof(struct mount_t));
  290.     struct mount_t *mount = &mounts[mount_i];
  291.     kstrcpy(mount->name, source);
  292.     mount->device = device;
  293.     mount->num_blocks = primary_descriptor.volume_space_size.little;
  294.     mount->block_size = primary_descriptor.logical_block_size.little;
  295.     mount->path_table_size = primary_descriptor.path_table_size.little;
  296.     mount->path_table_loc = primary_descriptor.l_path_table_location;
  297.     mount->root_entry = primary_descriptor.root_entry;
  298.  
  299.     return mount_i++;
  300. }
  301.  
  302. void init_iso9660(void) {
  303.     struct fs_t iso9660 = {0};
  304.  
  305.     kstrcpy(iso9660.type, "iso9660");
  306.     iso9660.mount = (void *)iso9660_mount;
  307.     iso9660.open = iso9660_open;
  308.  
  309.     vfs_install_fs(iso9660);
  310. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement