Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Created by MSM */
- /* Licensed under a Creative Commons Attribution 3.0 Unported License. */
- /* Parse and dump .iso files */
- #include <stdlib.h> // screw it
- #include <string.h> // screw char*s
- #include <stdint.h> // screw ints
- #include <stdbool.h> // screw ints
- #include <stdio.h> // screw iostream
- #include <stdarg.h> // screw good code
- #include <io.h> // screw portability
- #define RESERVED(X) _reserved ## X
- #define UNUSED(X) ((void)(X))
- #pragma pack(1)
- const size_t sector_size = 0x800;
- const unsigned ignored_sectors = 0x10;
- struct date_time_t;
- struct directory_record_t;
- struct volume_descriptor_common_t;
- struct volume_descriptor_generic_t;
- struct boot_descriptor_t;
- struct primary_descriptor_t;
- enum dir_flags;
- enum volume_type;
- void iso_dump_record_list(FILE *image, const char *relpath, int sector, size_t size);
- void iso_dump_record(FILE *image, const char *relpath, const struct directory_record_t *current, bool recorsive);
- void iso_dump_file(FILE *image, const char *relpath, int sector, size_t size);
- void iso_dump_descriptor(FILE *image, struct volume_descriptor_generic_t *desc);
- void iso_dump_primary_descriptor(FILE *image, struct primary_descriptor_t *desc);
- void iso_dump_boot_descriptor(FILE *image, struct boot_descriptor_t *desc);
- void iso_inspect_descriptors(FILE *image);
- const char *record_get_hr_name(const struct directory_record_t *record);
- void record_free_hr_name(const char *name);
- const char *path_combine(const char *dir, const char *sub);
- void path_free(const char *path);
- void fread_at(void *ptr, fpos_t from, size_t bytes, FILE *file);
- void iprintf(char *fmt, ...);
- void iindent();
- void iundent();
- void isetstr(const char *new_indent_str);
- enum dir_flags {
- df_hidden = 0x01,
- df_directory = 0x02,
- df_associated = 0x04,
- df_format_specified = 0x08,
- df_permissions_specified = 0x10,
- df_continue = 0x80
- };
- enum volume_type {
- vt_boot_descriptor,
- vt_primary_descriptor,
- vt_supplementart_descriptor,
- vt_partition_descriptor,
- vt_end = 0xFF
- };
- struct date_time_t {
- uint8_t years;
- uint8_t month;
- uint8_t day;
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
- int8_t greenwich_offset;
- };
- struct directory_record_t {
- uint8_t length;
- uint8_t ext_attrib_length;
- uint32_t extent_le;
- uint32_t extent_be;
- uint32_t data_length_le;
- uint32_t data_length_be;
- struct date_time_t recording_time;
- uint8_t flags;
- uint8_t file_unit_size;
- uint8_t interleave_gap_size;
- uint32_t volume_seq_number;
- uint8_t file_id_length;
- char file_id[];
- };
- struct volume_descriptor_common_t {
- uint8_t type;
- char magic[5];
- uint8_t version;
- };
- struct volume_descriptor_generic_t {
- struct volume_descriptor_common_t volume_data;
- char RESERVED(0)[2041];
- };
- struct boot_descriptor_t {
- struct volume_descriptor_common_t volume_data;
- char boot_system_id[32];
- char boot_id[32];
- char boot_system_use[1976];
- };
- struct primary_descriptor_t {
- struct volume_descriptor_common_t volume_data;
- uint8_t RESERVED(0);
- char system_id[32];
- char volume_id[32];
- char RESERVED(1)[8];
- uint64_t volume_space_size;
- char RESERVED(2)[32];
- uint32_t volume_set_size;
- uint32_t volume_seq_number;
- uint16_t logical_block_size_le;
- uint16_t logical_block_size_be;
- uint64_t path_table_size;
- uint32_t path_table_l_occurence;
- uint32_t path_table_l_optional_occurence;
- uint32_t path_table_m_occurence;
- uint32_t path_table_m_optional_occurence;
- struct directory_record_t root_directory;
- char ignored_rest[];
- };
- void fread_at(void *ptr, fpos_t from, size_t bytes, FILE *file) {
- fpos_t old_pos = ftell(file);
- fseek(file, from, SEEK_SET);
- fread(ptr, bytes, 1, file);
- fseek(file, old_pos, SEEK_SET);
- }
- const char *record_get_hr_name(const struct directory_record_t *record) {
- static const int self_dir_id = 0;
- static const int parent_dir_id = 1;
- size_t name_len;
- const char *name;
- if (record->file_id[0] == self_dir_id) {
- name_len = 1;
- name = ".";
- } else if (record->file_id[0] == parent_dir_id) {
- name_len = 2;
- name = "..";
- } else {
- name_len = record->file_id_length;
- name = record->file_id;
- for(int i = 0; i < (int)name_len; i++) {
- if (name[i] == ';') {
- name_len = i;
- break;
- }
- }
- if (name[name_len - 1] == '.') {
- name_len--;
- }
- }
- char *dyn_name = malloc(name_len + 1);
- sprintf(dyn_name, "%.*s", name_len, name);
- return dyn_name;
- }
- void record_free_hr_name(const char *record_name) {
- free((char*)record_name);
- }
- const char *path_combine(const char *dir, const char *sub) {
- int dir_len = strlen(dir);
- static const int slash_len = 1;
- int sub_len = strlen(sub);
- int total_len = dir_len + slash_len + sub_len;
- char *memory = malloc(total_len + 1);
- strcpy(memory, dir);
- memory[dir_len] = '/';
- strcpy(memory + dir_len + 1, sub);
- memory[total_len] = 0;
- return memory;
- }
- void path_free(const char *path) {
- free((char*)path);
- }
- unsigned iindent_level; // Teh ugly global variables
- const char *iindent_str;
- void iindent() {
- iindent_level++;
- }
- void iundent() {
- iindent_level--;
- }
- void isetstr(const char *new_indent_str) {
- iindent_str = new_indent_str;
- }
- void iprintf(char *fmt, ...) {
- for(int i = 0; i < (int)iindent_level; i++) {
- printf(iindent_str);
- }
- va_list args;
- va_start(args, fmt);
- vprintf(fmt, args);
- va_end(args);
- }
- void iso_dump_file(FILE *image, const char *relpath, int sector, size_t data_size) {
- FILE *newf = fopen(relpath, "wb");
- uint8_t *const file_data = malloc(data_size);
- fread_at(file_data, sector * sector_size, data_size, image);
- fwrite(file_data, data_size, 1, newf);
- fclose(newf);
- }
- void iso_dump_record_list(FILE *image, const char *relpath, int sector, size_t data_size) {
- uint8_t *const sector_data = malloc(sector_size);
- fread_at(sector_data, sector * sector_size, data_size, image);
- mkdir(relpath);
- uint8_t *current_record_ptr = sector_data;
- struct directory_record_t *current = (struct directory_record_t*)current_record_ptr;
- for(int ndx = 0; current->length != 0; ndx++) {
- iso_dump_record(image, relpath, current, ndx > 1);
- current_record_ptr += current->length;
- current = (struct directory_record_t*)current_record_ptr;
- }
- free(sector_data);
- }
- void iso_dump_record(FILE *image, const char *relpath, const struct directory_record_t *current, bool recursive) {
- const char *name = record_get_hr_name(current);
- bool is_dir = current->flags & df_directory;
- iprintf("- %s%s%s\n",
- is_dir ? "[" : "",
- name,
- is_dir ? "]" : "");
- if (recursive) {
- iindent();
- const char *childpath = path_combine(relpath, name);
- if (is_dir) {
- iso_dump_record_list(image, childpath, current->extent_le, current->data_length_le);
- } else {
- iso_dump_file(image, childpath, current->extent_le, current->data_length_le);
- }
- path_free(childpath);
- iundent();
- }
- record_free_hr_name(name);
- }
- void iso_dump_boot_descriptor(FILE *image, struct boot_descriptor_t *desc) {
- UNUSED(image);
- iprintf("Known Type: Boot Descriptor\n");
- iprintf("Boot System ID: %.32s\n", desc->boot_system_id);
- iprintf("Boot ID: %.32s\n", desc->boot_id);
- }
- void iso_dump_primary_descriptor(FILE *image, struct primary_descriptor_t *desc) {
- iprintf("Known Type: Primary Descriptor\n");
- iprintf("System ID: %.32s\n", desc->system_id);
- iprintf("Volume ID: %.32s\n", desc->volume_id);
- iprintf("Logical Block Size: %x\n", desc->logical_block_size_le);
- iprintf("Filesystem Dump\n");
- iso_dump_record(image, "Root", &desc->root_directory, true);
- }
- void iso_dump_descriptor(FILE *image, struct volume_descriptor_generic_t *desc) {
- struct volume_descriptor_common_t common = desc->volume_data;
- printf("\nFound Descriptor <type=%X> <magic=%.5s> <version=%X>\n",
- common.type, common.magic, common.version);
- isetstr(" ");
- iindent();
- if (common.type == vt_primary_descriptor) {
- iso_dump_primary_descriptor(image, (struct primary_descriptor_t*)desc);
- } else if (common.type == vt_boot_descriptor) {
- iso_dump_boot_descriptor(image, (struct boot_descriptor_t*)desc);
- }
- iundent();
- }
- void iso_inspect_descriptors(FILE *image) {
- struct volume_descriptor_generic_t generic_desc;
- fseek(image, ignored_sectors * sector_size, SEEK_SET);
- do {
- fread(&generic_desc, sizeof(generic_desc), 1, image);
- iso_dump_descriptor(image, &generic_desc);
- } while(generic_desc.volume_data.type != vt_end);
- }
- int main() {
- FILE *test = fopen("iso.iso", "rb");
- iso_inspect_descriptors(test);
- return 0;
- }
- /* You might also want to have a look at (my forum post, in polish)
- http://forum.4programmers.net/Newbie/203080-montowanie_obrazow_plyt?p=874744#id874744
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement