188 lines
4.5 KiB
C++
188 lines
4.5 KiB
C++
#pragma once
|
|
|
|
typedef struct {
|
|
char year[4];
|
|
char month[2];
|
|
char day[2];
|
|
char hour[2];
|
|
char minute[2];
|
|
char second[2];
|
|
char hundredths[2];
|
|
int8_t timezone;
|
|
} __attribute__((packed)) iso_9660_datetime_t;
|
|
|
|
typedef struct {
|
|
uint8_t year;
|
|
uint8_t month;
|
|
uint8_t day;
|
|
uint8_t hour;
|
|
uint8_t minute;
|
|
uint8_t second;
|
|
int8_t timezone;
|
|
} __attribute__((packed)) iso_9660_rec_date_t;
|
|
|
|
typedef struct {
|
|
uint8_t length;
|
|
uint8_t ext_length;
|
|
|
|
uint32_t extent_start_LSB;
|
|
uint32_t extent_start_MSB;
|
|
|
|
uint32_t extent_length_LSB;
|
|
uint32_t extent_length_MSB;
|
|
|
|
iso_9660_rec_date_t record_date;
|
|
|
|
uint8_t flags;
|
|
uint8_t interleave_units;
|
|
uint8_t interleave_gap;
|
|
|
|
uint16_t volume_seq_LSB;
|
|
uint16_t volume_seq_MSB;
|
|
|
|
uint8_t name_len;
|
|
char name[];
|
|
} __attribute__((packed)) iso_9660_directory_entry_t;
|
|
|
|
typedef struct {
|
|
uint8_t type; /* 0x01 */
|
|
char id[5]; /* CD001 */
|
|
|
|
uint8_t version;
|
|
uint8_t _unused0;
|
|
|
|
char system_id[32];
|
|
char volume_id[32];
|
|
|
|
uint8_t _unused1[8];
|
|
|
|
uint32_t volume_space_LSB;
|
|
uint32_t volume_space_MSB;
|
|
|
|
uint8_t _unused2[32];
|
|
|
|
uint16_t volume_set_LSB;
|
|
uint16_t volume_set_MSB;
|
|
|
|
uint16_t volume_seq_LSB;
|
|
uint16_t volume_seq_MSB;
|
|
|
|
uint16_t logical_block_size_LSB;
|
|
uint16_t logical_block_size_MSB;
|
|
|
|
uint32_t path_table_size_LSB;
|
|
uint32_t path_table_size_MSB;
|
|
|
|
uint32_t path_table_LSB;
|
|
uint32_t optional_path_table_LSB;
|
|
|
|
uint32_t path_table_MSB;
|
|
uint32_t optional_path_table_MSB;
|
|
|
|
/* iso_9660_directory_entry_t */
|
|
char root[34];
|
|
|
|
char volume_set_id[128];
|
|
char volume_publisher[128];
|
|
char data_preparer[128];
|
|
char application_id[128];
|
|
|
|
char copyright_file[38];
|
|
char abstract_file[36];
|
|
char bibliographic_file[37];
|
|
|
|
iso_9660_datetime_t creation;
|
|
iso_9660_datetime_t modification;
|
|
iso_9660_datetime_t expiration;
|
|
iso_9660_datetime_t effective;
|
|
|
|
uint8_t file_structure_version;
|
|
uint8_t _unused_3;
|
|
|
|
char application_use[];
|
|
} __attribute__((packed)) iso_9660_volume_descriptor_t;
|
|
|
|
#define ISO_SECTOR_SIZE 2048
|
|
|
|
#define FLAG_HIDDEN 0x01
|
|
#define FLAG_DIRECTORY 0x02
|
|
#define FLAG_ASSOCIATED 0x04
|
|
#define FLAG_EXTENDED 0x08
|
|
#define FLAG_PERMISSIONS 0x10
|
|
#define FLAG_CONTINUES 0x80
|
|
|
|
static int root_sector = 0;
|
|
static iso_9660_volume_descriptor_t * root = (iso_9660_volume_descriptor_t *)((uint8_t *)0x20000);
|
|
static iso_9660_directory_entry_t * dir_entry = (iso_9660_directory_entry_t *)((uint8_t *)0x20800);
|
|
static uint8_t * mod_dir = (uint8_t *)0x21000;
|
|
static uint8_t * dir_entries = (uint8_t *)(0x30000);
|
|
static struct ata_device * device = 0;
|
|
|
|
static int navigate(char * name) {
|
|
memset(dir_entries, 2048, 0xA5);
|
|
//print("reading from sector ");
|
|
//print_hex(dir_entry->extent_start_LSB);
|
|
//print("\n");
|
|
ata_device_read_sector_atapi(device, dir_entry->extent_start_LSB, dir_entries);
|
|
ata_device_read_sector_atapi(device, dir_entry->extent_start_LSB+1, dir_entries + 2048);
|
|
ata_device_read_sector_atapi(device, dir_entry->extent_start_LSB+2, dir_entries + 4096);
|
|
|
|
long offset = 0;
|
|
while (1) {
|
|
iso_9660_directory_entry_t * dir = (iso_9660_directory_entry_t *)(dir_entries + offset);
|
|
if (dir->length == 0) {
|
|
if (offset < dir_entry->extent_length_LSB) {
|
|
offset += 1; // this->block_size - ((uintptr_t)offset % this->block_size);
|
|
goto try_again;
|
|
}
|
|
break;
|
|
}
|
|
if (!(dir->flags & FLAG_HIDDEN)) {
|
|
char file_name[dir->name_len + 1];
|
|
memcpy(file_name, dir->name, dir->name_len);
|
|
file_name[dir->name_len] = 0;
|
|
char * s = strchr(file_name,';');
|
|
if (s) {
|
|
*s = '\0';
|
|
}
|
|
#if 0
|
|
print("Found a file: ");
|
|
print(" Name: ");
|
|
print(file_name); print("\n");
|
|
#endif
|
|
if (!strcmp(file_name, name)) {
|
|
memcpy(dir_entry, dir, sizeof(iso_9660_directory_entry_t));
|
|
return 1;
|
|
}
|
|
}
|
|
offset += dir->length;
|
|
try_again:
|
|
if ((long)(offset) > dir_entry->extent_length_LSB) break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void restore_root(void) {
|
|
memcpy(dir_entry, (iso_9660_directory_entry_t *)&root->root, sizeof(iso_9660_directory_entry_t));
|
|
|
|
#if 0
|
|
print("Root restored.");
|
|
print("\n Entry len: "); print_hex( dir_entry->length);
|
|
print("\n File start: "); print_hex( dir_entry->extent_start_LSB);
|
|
print("\n File len: "); print_hex( dir_entry->extent_length_LSB);
|
|
print("\n");
|
|
#endif
|
|
}
|
|
|
|
static void restore_mod(void) {
|
|
memcpy(dir_entry, (iso_9660_directory_entry_t *)mod_dir, sizeof(iso_9660_directory_entry_t));
|
|
#if 0
|
|
print("mod restored.");
|
|
print("\n Entry len: "); print_hex( dir_entry->length);
|
|
print("\n File start: "); print_hex( dir_entry->extent_start_LSB);
|
|
print("\n File len: "); print_hex( dir_entry->extent_length_LSB);
|
|
print("\n");
|
|
#endif
|
|
}
|