diff options
Diffstat (limited to 'Xenogears/reinsert.cpp')
-rw-r--r-- | Xenogears/reinsert.cpp | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/Xenogears/reinsert.cpp b/Xenogears/reinsert.cpp new file mode 100644 index 0000000..e58b871 --- /dev/null +++ b/Xenogears/reinsert.cpp @@ -0,0 +1,305 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "fileutils.h" +#include "cdutils.h" +#include "generic.h" + +unsigned int tourne = 0; + +struct t_index_tab { + unsigned long address; + long size; + long type; + long index; +}; + +struct t_sequence { + unsigned int n; + unsigned int sum; + char *prefix; + char *name; + int type; +}; + +char *title, *iso_filename, *tbl_filename, *prefix, *in_filename; +unsigned long iso_size; +unsigned int nb_records, nb_seqs = 0; +struct t_sequence sequences[1000]; + +int slus_index = -1, force = 0; + +long check_iso(int f_iso); +void write_files(int f_iso_r, int f_iso_w, int f_in, int fileindex); +int process_def_file(int f_def); + +unsigned char user_data[2352]; + +void usage(char ** argv) { + fprintf(stderr, "Usage: %s <definition_file.sqr> <iso_file_name> <file_index> <filename> [-f]\nSee readme.txt for details\n", + argv[0]); + exit(-1); +} + +int main(int argc, char **argv) +{ + int f_def, f_iso_r, f_iso_w, f_in; + int fileindex; + + verbosity = 1; + + fprintf(stderr, "Xenogears File Insertor by Nicolas \"Pixel\" Noble\n\n"); + + if ((argc != 5) && (argc != 6)) { + usage(argv); + } + + if (argc == 6) { + if (strcmp(argv[5], "-f")) { + usage(argv); + } else { + force = 1; + } + } + + printm(M_STATUS, "Processing file %s...\n", argv[1]); + + if ((f_def = open(argv[1], O_RDONLY)) < 0) { + printm(M_ERROR, "Unable to open the definition file \"%s\"...\n", argv[1]); + exit(-1); + } + + if (process_def_file(f_def)) { + close(f_def); + printm(M_ERROR, "Unable to process the definition file \"%s\"...\n", argv[1]); + exit(-1); + } + + iso_filename = argv[2]; + + printm(M_STATUS, "Begin processing iso file.\n"); + if ((f_iso_r = open(iso_filename, O_RDONLY)) < 0) { + printm(M_ERROR, "Unable to open the iso file \"%s\"...\n", iso_filename); + exit(-1); + } + + if ((f_iso_w = open(iso_filename, O_WRONLY)) < 0) { + printm(M_ERROR, "Unable to open the iso file \"%s\"...\n", iso_filename); + exit(-1); + } + + if (check_iso(f_iso_r)) { + printm(M_ERROR, "Invalid iso file for %s\n", title); + printm(M_ERROR, "===> Make sure you are using a Genuine iso file.\n"); + } else { + printm(M_INFO, "Genuine %s iso detected.\n", title); + } + + fileindex = atoi(argv[3]); + in_filename = argv[4]; + if ((f_in = open(in_filename, O_RDONLY)) < 0) { + printm(M_ERROR, "Unable to open the file \"%s\"...\n", in_filename); + exit(-1); + } + + printm(M_STATUS, "Entering files write sequence\n"); + write_files(f_iso_r, f_iso_w, f_in, fileindex); + close(f_iso_r); + close(f_iso_w); + exit(0); +} + +/* + * Ugly but working... for now + */ +int process_def_file(int h_f_def) +{ + char t[1024], *p; + unsigned int n, sum = 0; + FILE * f_def = fdopen(h_f_def, "r"); + + if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL) + return 1; + *p = 0; + printm(M_INFO, "Read title: %s\n", t); + title = strdup(t); + + if (fscanf(f_def, "%lu\n", &iso_size) != 1) + return 1; + printm(M_INFO, "Read iso size: %lu bytes\n", iso_size); + + if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL) + return 1; + *p = 0; + printm(M_INFO, "Read index table filename: %s\n", t); + tbl_filename = strdup(t); + + if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL) + return 1; + *p = 0; + printm(M_INFO, "Read global directory prefix: %s\n", t); + prefix = strdup(t); + + if (fscanf(f_def, "%u\n", &nb_records) != 1) + return 1; + printm(M_INFO, "Read total of records: %u\n", nb_records); + + while (1) { + if (fscanf(f_def, "%u\n", &n) != 1) + return 1; + if (!n) { + if (sum == nb_records) { + printm(M_INFO, "Definition file seems coherent\n"); + return 0; + } else { + printm(M_ERROR, "Definition file incoherent\n"); + return 1; + } + } + sum += n; + sequences[nb_seqs].n = n; + sequences[nb_seqs].sum = sum; + if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL) + return 1; + *p = 0; + sequences[nb_seqs].prefix = strdup(t); + if (fscanf(f_def, "%u\n", &n) != 1) + return 1; + sequences[nb_seqs].type = n; + if ((p = strchr(fgets(t, 1024, f_def), '\n')) == NULL) + return 1; + *p = 0; + sequences[nb_seqs].name = strdup(t); + printm(M_INFO, "Read definition of sequence %i:\n===> %5i (sum = %5i) chunks of %s (%s)\n", + nb_seqs, n, sum, t, sequences[nb_seqs].prefix); + nb_seqs++; + } +} + +long check_iso(int f_iso) +{ + unsigned long length; + + length = filesize(f_iso); + printm(M_INFO, "Filesize of iso file %s is %ld bytes\n", iso_filename, length); + if (length != iso_size) { + return 1; + } + return 0; +} + +#define INDEXPOS 24 + +void rewrite_fat(int f_iso_r, int f_iso_w, unsigned char * new_fat) { + unsigned char old_fat[34816]; + int i; + + sector_seek(f_iso_w, INDEXPOS); + for (i = INDEXPOS; i < (INDEXPOS + 16); i++) { + printm(M_INFO, "Writing fat sector %lu\n", i); + write_sector(f_iso_r, f_iso_w, &new_fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1); + } + + sector_seek(f_iso_r, slus_index + 1); + for (i = slus_index + 1; i < (slus_index + 18); i++) { + printm(M_INFO, "Reading SLUS sector %lu\n", i); + read_sector(f_iso_r, &old_fat[2048 * (i - slus_index - 1)], MODE_2_FORM_1); + } + + bcopy((char *) new_fat, (char *) old_fat + 4, 32768); + sector_seek(f_iso_w, slus_index + 1); + for (i = slus_index + 1; i < (slus_index + 18); i++) { + printm(M_INFO, "Writing SLUS sector %lu\n", i); + write_sector(f_iso_r, f_iso_w, &old_fat[2048 * (i - slus_index - 1)], MODE_2_FORM_1); + } +} + +void write_files(int f_iso_r, int f_iso_w, int f_in, int fileindex) +{ + t_index_tab index_tab[10000]; + unsigned char t[8]; + unsigned long i; + unsigned long j; + unsigned int seq = 0; + unsigned long indexer; + struct t_index_tab *p = (struct t_index_tab *) t; + + long old_file_size, new_file_size, old_nb_sects, new_nb_sects; + unsigned char fat[32768]; + + sector_seek(f_iso_r, INDEXPOS); + for (i = INDEXPOS; i < (INDEXPOS + 16); i++) { + printm(M_INFO, "Reading fat sector %lu\n", i); + read_sector(f_iso_r, &fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1); + } + + indexer = 0; + for (j = 0; j < 32768; j = j + 7) { + t[0] = 0; + bcopy((char *) &fat[j], (char *) t + 1, 7); + p->address >>= 8; + index_tab[indexer] = *p; + if (p->size > 0 && p->address != 0) { + index_tab[indexer].index = j / 7; + printm(M_INFO, "Found a quite valid index: number %4lu, address %6lu, size %3li\n", + indexer, index_tab[indexer].address, index_tab[indexer].size); + indexer++; + if (indexer == nb_records) + break; + } else { + printm(M_WARNING, "Ignored invalid index chunk number %4lu (size = %lu) (%02x %02x %02x %02x %02x %02x %02x)\n", + j / 7, -index_tab[indexer].size, t[0], t[1], t[2], t[4], t[5], t[6], t[7]); + } + } + printm(M_STATUS, "Index file generation complete.\n\n"); + + for (i = 0; i < nb_records; i++) { + if (sequences[seq].sum == i) + seq++; + index_tab[i].type = sequences[seq].type; + if (!strcmp(sequences[seq].prefix, "SLUS")) { + if (slus_index >= 0) { + printm(M_ERROR, "Two SLUS files defined\n"); + exit(-1); + } + slus_index = index_tab[i].address; + } + } + + if (slus_index < 0) { + printm(M_ERROR, "No SLUS file defined\n"); + exit(-1); + } + + printm(M_INFO, "SLUS file found at sector %6i\n", slus_index); + + new_file_size = filesize(f_in); + old_file_size = index_tab[fileindex].size; + + new_nb_sects = new_file_size / sec_sizes[index_tab[fileindex].type]; + old_nb_sects = old_file_size / sec_sizes[index_tab[fileindex].type]; + + if (new_file_size % sec_sizes[index_tab[fileindex].type]) { + new_nb_sects++; + } + + if (old_file_size % sec_sizes[index_tab[fileindex].type]) { + old_nb_sects++; + } + + if (new_nb_sects > old_nb_sects) { + printm(M_ERROR, "New file too big.\n"); + if (!force) { + exit(-1); + } + } + + printm(M_INFO, "New file size: %12li, old file size: %12li\n", new_file_size, old_file_size); + printm(M_INFO, "New file ssize: %12li, old file ssize: %12li\n", new_nb_sects, old_nb_sects); + + printm(M_INFO, "File address: %6i\n", index_tab[fileindex].address); + + write_file(f_iso_r, f_iso_w, f_in, index_tab[fileindex].type, index_tab[fileindex].address); + *((long *)(&fat[index_tab[fileindex].index * 7 + 3])) = new_file_size; + rewrite_fat(f_iso_r, f_iso_w, fat); +} |