#include #include #include #include "cdutils.h" #include "generic.h" #include "Input.h" #include "Output.h" #include "Main.h" CODE_BEGINS public: Appli() : tourne(0), nb_seqs(0), f_def(0), f_iso_r(0), f_iso_w(0), f_in(0), cdutil(0), slus_index(-1), force(0) {} virtual ~Appli() { delete cdutil; delete f_def; delete f_iso_r; delete f_iso_w; delete f_in; } private: unsigned int tourne; struct t_index_tab { unsigned long address; long size; long type; long index; }; struct t_sequence { unsigned int n; unsigned int sum; String prefix; String name; int type; }; String title, iso_filename, prefix, in_filename; unsigned long iso_size; unsigned int nb_records, nb_seqs; struct t_sequence sequences[1000]; Handle * f_def, * f_iso_r, * f_iso_w, * f_in; cdutils * cdutil; int slus_index, force; unsigned char user_data[2352]; void usage() throw (GeneralException) { printm(M_BARE, "Usage: %s [-f]\nSee readme.txt for details\n", argv[0]); throw Exit(-1); } virtual int startup() throw (GeneralException) { int fileindex; verbosity = 1; printm(M_BARE, "Xenogears File Insertor by Nicolas \"Pixel\" Noble\n\n"); if ((argc != 5) && (argc != 6)) { usage(); } if (argc == 6) { if (strcmp(argv[5], "-f")) { usage(); } else { force = 1; } } printm(M_STATUS, "Processing file %s...\n", argv[1]); f_def = new Input(argv[1]); if (process_def_file(f_def)) { printm(M_ERROR, "Unable to process the definition file \"%s\"...\n", argv[1]); throw Exit(-1); } iso_filename = argv[2]; printm(M_STATUS, "Begin processing iso file.\n"); f_iso_r = new Input(iso_filename); f_iso_w = new Output(iso_filename, 0, 0); f_iso_w->seek(0, SEEK_SET); cdutil = new cdutils(f_iso_r, f_iso_w); if (check_iso()) { printm(M_ERROR, "Invalid iso file for " + title + "\n"); printm(M_ERROR, "===> Make sure you are using a Genuine iso file.\n"); throw Exit(-1); } else { printm(M_INFO, "Genuine " + title + " iso detected.\n"); } fileindex = atoi(argv[3]); in_filename = argv[4]; f_in = new Input(in_filename); printm(M_STATUS, "Entering files write sequence\n"); write_files(fileindex); return 0; } /* * Ugly but working... for now */ int process_def_file(Handle * f_def) { unsigned int n, sum = 0; String t; *f_def >> t; printm(M_INFO, "Read title: " + t + "\n"); title = t; *f_def >> t; iso_size = t.to_int(); printm(M_INFO, "Read iso size: %lu bytes\n", iso_size); *f_def >> t; printm(M_INFO, "Read global directory prefix: " + t + "\n"); prefix = t; *f_def >> t; nb_records = t.to_int(); printm(M_INFO, "Read total of records: %u\n", nb_records); while (1) { *f_def >> t; n = t.to_int(); 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; *f_def >> t; sequences[nb_seqs].prefix = t; *f_def >> t; n = t.to_int(); sequences[nb_seqs].type = n; *f_def >> t; sequences[nb_seqs].name = t; printm(M_INFO, "Read definition of sequence %i:\n===> %5i (sum = %5i) chunks of " + t + " (" + sequences[nb_seqs].prefix + ")\n", nb_seqs, n, sum); nb_seqs++; } } long check_iso() { unsigned long length; length = f_iso_r->GetSize(); printm(M_INFO, "Filesize of iso file " + iso_filename + " is %ld bytes\n", length); if (length != iso_size) { return 1; } return 0; } #define INDEXPOS 24 void rewrite_fat(Byte * new_fat) { unsigned char old_fat[34816]; int i; cdutil->sector_seek(INDEXPOS); for (i = INDEXPOS; i < (INDEXPOS + 16); i++) { printm(M_INFO, "Writing fat sector %lu\n", i); cdutil->write_sector(&new_fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1); } cdutil->sector_seek(slus_index + 1); for (i = slus_index + 1; i < (slus_index + 18); i++) { printm(M_INFO, "Reading SLUS sector %lu\n", i); cdutil->read_sector(&old_fat[2048 * (i - slus_index - 1)], MODE_2_FORM_1); } bcopy((char *) new_fat, (char *) old_fat + 4, 32768); cdutil->sector_seek(slus_index + 1); for (i = slus_index + 1; i < (slus_index + 18); i++) { printm(M_INFO, "Writing SLUS sector %lu\n", i); cdutil->write_sector(&old_fat[2048 * (i - slus_index - 1)], MODE_2_FORM_1); } } void write_files(int fileindex) throw (GeneralException) { 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]; cdutil->sector_seek(INDEXPOS); for (i = INDEXPOS; i < (INDEXPOS + 16); i++) { printm(M_INFO, "Reading fat sector %lu\n", i); cdutil->read_sector(&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 (sequences[seq].prefix == "SLUS") { if (slus_index >= 0) { printm(M_ERROR, "Two SLUS files defined\n"); throw Exit(-1); } slus_index = index_tab[i].address; } } if (slus_index < 0) { printm(M_ERROR, "No SLUS file defined\n"); throw Exit(-1); } printm(M_INFO, "SLUS file found at sector %6i\n", slus_index); new_file_size = f_in->GetSize(); 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) { throw 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); cdutil->write_file(f_in, index_tab[fileindex].type, index_tab[fileindex].address); *((long *)(&fat[index_tab[fileindex].index * 7 + 3])) = new_file_size; rewrite_fat(fat); } CODE_ENDS