diff options
Diffstat (limited to 'VP/main_dump.cpp')
-rw-r--r-- | VP/main_dump.cpp | 568 |
1 files changed, 284 insertions, 284 deletions
diff --git a/VP/main_dump.cpp b/VP/main_dump.cpp index 5add9b3..9fa4dfa 100644 --- a/VP/main_dump.cpp +++ b/VP/main_dump.cpp @@ -1,284 +1,284 @@ -/*
- * Valkyrie Profile extractor by Nicolas "Pixel" Noble (nicolas@nobis-crew.org)
- * Highly based upon Yazoo's Chrono Cross CD extractor
- *
- * ******** Original disclaimer by Yazoo ********
- *
- * Chrono Cross CD extractor Copyright 2000-2001 by Yazoo (hamm@efrei.fr) Revision 0.1b ANSI C
- *
- *
- * Features:
- *
- * Dump the complete content of Chrono Chross CD1/CD2 US and Japanese version It requires a iso
- * named Chrono1.iso in the same directory
- *
- * Todo list:
- *
- * Find a way to locate end of the last file Better support for CD2 Dump in subdirectory according
- * to CD1/CD2 repartition Recompilation in Visual C++ 6 for disk speed optimisation Source comment
- * and reorganisation Log feature (Optional since you can redirect output with > ) Progression
- * indicator Better detection of the ISO with error control Major code optimisation Integration in
- * main Chrono Cross Hacking tool
- *
- * ******** End of original disclaimer by Yazoo ********
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "cdutils.h"
-#include "generic.h"
-#include "Input.h"
-#include "Output.h"
-#include "BString.h"
-#include "Main.h"
-#include "cdabstract.h"
-
-CODE_BEGINS
-public:
-Appli() : tourne(0), nb_seqs(0), f_def(0), f_iso(0), f_out(0), cdutil(0) {}
-virtual ~Appli() {
- delete cdutil;
- delete f_def;
- delete f_iso;
- delete f_out;
-}
-private:
-
-unsigned int tourne;
-
-struct t_index_tab {
- unsigned long address;
- unsigned char flags;
- long type;
- long index;
-};
-
-struct t_sequence {
- unsigned int n;
- unsigned int sum;
- String prefix;
- String name;
- int type;
-};
-
-String title, iso_filename, prefix;
-unsigned long iso_size;
-unsigned int nb_records, nb_seqs;
-struct t_sequence sequences[1000];
-Handle * f_def, * f_iso, * f_out;
-cdutils * cdutil;
-
-unsigned char user_data[2352];
-
-virtual int startup() throw (GeneralException)
-{
- verbosity = M_STATUS;
-
- fprintf(stderr,
-"Valkyrie Profile File Extractor by Nicolas \"Pixel\" Noble\n"
-"Highly based upon the Chrono Cross File Extractor By Yazoo\n\n");
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <definition_file.sqr> <iso_file_name>\nSee readme.txt for details\n",
- argv[0]);
- throw Exit(-1);
- }
-
- printm(M_STATUS, "Processing file %s...\n", argv[1]);
-
- f_def = new Input(argv[1]);
-
- if (process_def_file()) {
- 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 = open_iso(iso_filename);
-
- 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");
- } else {
- printm(M_INFO, "Genuine " + title + " iso detected.\n");
- }
-
- cdutil = new cdutils(f_iso);
-
- printm(M_STATUS, "Entering files read sequence\n");
- read_files();
- throw Exit(0);
-}
-
-/*
- * Ugly but working... for now
- */
-int process_def_file()
-{
- String t;
- unsigned int n, sum = 0;
-
- *f_def >> title;
- printm(M_INFO, "Read title: " + title + "\n");
-
- *f_def >> t;
- iso_size = t.to_int();
- printm(M_INFO, "Read iso size: %lu bytes\n", iso_size);
-
- *f_def >> prefix;
- printm(M_INFO, "Read global directory prefix: " + prefix + "\n");
-
- *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 >> sequences[nb_seqs].prefix;
- *f_def >> t;
- sequences[nb_seqs].type = t.to_int();
- *f_def >> sequences[nb_seqs].name;
- printm(M_INFO, "Read definition of sequence %i:\n===> %5i (sum = %5i) chunks of " + sequences[nb_seqs].name + " (" + sequences[nb_seqs].prefix + ")\n",
- nb_seqs, n, sum);
- nb_seqs++;
- }
-}
-
-long check_iso()
-{
- unsigned long length;
-
- length = f_iso->GetSize();
- if (length < 0) {
- printm(M_INFO, "Can not get file size, assuming reading from cd.\n");
- } else {
- printm(M_INFO, "Filesize of iso file " + iso_filename + " is %ld bytes\n", length);
- if (length != iso_size) {
- return 1;
- }
- }
- return 0;
-}
-
-void read_files()
-{
- t_index_tab index_tab[10000];
- unsigned long i;
- unsigned long j;
- unsigned int seq = 0;
- unsigned long indexer;
-
- unsigned char fat[20480];
- unsigned char key[256];
-
-#define INDEXPOS 150
-
- cdutil->sector_seek(INDEXPOS);
- for (i = INDEXPOS; i < (INDEXPOS + 10); i++) {
- printm(M_INFO, "Reading fat sector %lu\n", i);
- cdutil->read_sector(&fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1);
- }
-
- memcpy(key, fat + 0x4f00, 256);
-
- printm(M_INFO, "Decrypting.\n");
- for (i = 0; i < 20480; i++) {
- fat[i] ^= key[i % 256];
- }
-
- indexer = 0;
- for (j = 4; j < 20480; j += 4) {
- unsigned char m, s, f;
- m = fat[j];
- s = fat[j + 1];
- f = fat[j + 2];
- index_tab[indexer].address = cdutil->from_MSF(m, s, f);
- if (m || s || f) {
- index_tab[indexer].index = j / 4;
- index_tab[indexer].flags = fat[j + 3];
- printm(M_INFO, "Found a quite valid index: number %4lu, address %6lu - flags = %02x\n",
- indexer, index_tab[indexer].address, fat[j + 3]);
- indexer++;
- if (indexer == nb_records)
- break;
- } else {
- printm(M_WARNING, "Ignored invalid index chunk number %4lu\n", j / 4);
- }
- }
- printm(M_STATUS, "Index file generation complete.\n\n");
- index_tab[indexer].address = f_iso->GetSize() / 2352;
-
- for (i = 0; i < nb_records; i++) {
- if (sequences[seq].sum == i)
- seq++;
- index_tab[i].type = sequences[seq].type;
- if (sequences[seq].type == 0) {
- printm(M_INFO, "%6lu - %02x: ignored\n", index_tab[i].address, index_tab[i].flags);
- } else {
- int size;
- printm(M_INFO, "%6lu - %02x: ", index_tab[i].address, index_tab[i].flags);
- size = index_tab[i + 1].address - index_tab[i].address;
- size *= sec_sizes[index_tab[i].type];
- file_dump(index_tab[i].address, size, i, seq);
- if (verbosity >= M_INFO) {
- fprintf(stderr, "\n");
- }
- }
- }
- fprintf(stderr, "\n");
-}
-
-void file_dump(unsigned long debut, unsigned long taille, long num, int seq)
-{
- long i;
- long nbsects;
- String nom;
- char type = sequences[seq].type;
- char ptitbidule[] = "-\\|/";
-
- nom = "./" + prefix + "/";
- MKDIR(nom.to_charp());
-
- nom += sequences[seq].prefix + "/";
- MKDIR(nom.to_charp());
-
- nom += String().set("%04ld.out", num);
-
- f_out = new Output(nom);
- nbsects = taille / sec_sizes[type];
- if (taille % sec_sizes[type])
- nbsects++;
- cdutil->sector_seek(debut);
- for (i = 0; i < nbsects; i++) {
- if (verbosity < M_INFO)
- fprintf(stderr, " (%c)\010\010\010\010\010", ptitbidule[((tourne++) >> 8) % 4]);
- cdutil->read_sector(user_data, type);
- if (i != (nbsects - 1)) {
- f_out->write(user_data, sec_sizes[type]);
- } else {
- f_out->write(user_data, taille % sec_sizes[type] ? taille % sec_sizes[type] : sec_sizes[type]);
- }
- }
- delete f_out;
- f_out = 0;
- printm(M_BARE, " (*) Dumped file number %4ld - type \"" + sequences[seq].name + "\" \r", num);
-}
-CODE_ENDS
+/* + * Valkyrie Profile extractor by Nicolas "Pixel" Noble (nicolas@nobis-crew.org) + * Highly based upon Yazoo's Chrono Cross CD extractor + * + * ******** Original disclaimer by Yazoo ******** + * + * Chrono Cross CD extractor Copyright 2000-2001 by Yazoo (hamm@efrei.fr) Revision 0.1b ANSI C + * + * + * Features: + * + * Dump the complete content of Chrono Chross CD1/CD2 US and Japanese version It requires a iso + * named Chrono1.iso in the same directory + * + * Todo list: + * + * Find a way to locate end of the last file Better support for CD2 Dump in subdirectory according + * to CD1/CD2 repartition Recompilation in Visual C++ 6 for disk speed optimisation Source comment + * and reorganisation Log feature (Optional since you can redirect output with > ) Progression + * indicator Better detection of the ISO with error control Major code optimisation Integration in + * main Chrono Cross Hacking tool + * + * ******** End of original disclaimer by Yazoo ******** + * + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include "cdutils.h" +#include "generic.h" +#include "Input.h" +#include "Output.h" +#include "BString.h" +#include "Main.h" +#include "cdabstract.h" + +CODE_BEGINS +public: +Appli() : tourne(0), nb_seqs(0), f_def(0), f_iso(0), f_out(0), cdutil(0) {} +virtual ~Appli() { + delete cdutil; + delete f_def; + delete f_iso; + delete f_out; +} +private: + +unsigned int tourne; + +struct t_index_tab { + unsigned long address; + unsigned char flags; + long type; + long index; +}; + +struct t_sequence { + unsigned int n; + unsigned int sum; + String prefix; + String name; + int type; +}; + +String title, iso_filename, prefix; +unsigned long iso_size; +unsigned int nb_records, nb_seqs; +struct t_sequence sequences[1000]; +Handle * f_def, * f_iso, * f_out; +cdutils * cdutil; + +unsigned char user_data[2352]; + +virtual int startup() throw (GeneralException) +{ + verbosity = M_STATUS; + + fprintf(stderr, +"Valkyrie Profile File Extractor by Nicolas \"Pixel\" Noble\n" +"Highly based upon the Chrono Cross File Extractor By Yazoo\n\n"); + + if (argc != 3) { + fprintf(stderr, "Usage: %s <definition_file.sqr> <iso_file_name>\nSee readme.txt for details\n", + argv[0]); + throw Exit(-1); + } + + printm(M_STATUS, "Processing file %s...\n", argv[1]); + + f_def = new Input(argv[1]); + + if (process_def_file()) { + 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 = open_iso(iso_filename); + + 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"); + } else { + printm(M_INFO, "Genuine " + title + " iso detected.\n"); + } + + cdutil = new cdutils(f_iso); + + printm(M_STATUS, "Entering files read sequence\n"); + read_files(); + throw Exit(0); +} + +/* + * Ugly but working... for now + */ +int process_def_file() +{ + String t; + unsigned int n, sum = 0; + + *f_def >> title; + printm(M_INFO, "Read title: " + title + "\n"); + + *f_def >> t; + iso_size = t.to_int(); + printm(M_INFO, "Read iso size: %lu bytes\n", iso_size); + + *f_def >> prefix; + printm(M_INFO, "Read global directory prefix: " + prefix + "\n"); + + *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 >> sequences[nb_seqs].prefix; + *f_def >> t; + sequences[nb_seqs].type = t.to_int(); + *f_def >> sequences[nb_seqs].name; + printm(M_INFO, "Read definition of sequence %i:\n===> %5i (sum = %5i) chunks of " + sequences[nb_seqs].name + " (" + sequences[nb_seqs].prefix + ")\n", + nb_seqs, n, sum); + nb_seqs++; + } +} + +long check_iso() +{ + unsigned long length; + + length = f_iso->GetSize(); + if (length < 0) { + printm(M_INFO, "Can not get file size, assuming reading from cd.\n"); + } else { + printm(M_INFO, "Filesize of iso file " + iso_filename + " is %ld bytes\n", length); + if (length != iso_size) { + return 1; + } + } + return 0; +} + +void read_files() +{ + t_index_tab index_tab[10000]; + unsigned long i; + unsigned long j; + unsigned int seq = 0; + unsigned long indexer; + + unsigned char fat[20480]; + unsigned char key[256]; + +#define INDEXPOS 150 + + cdutil->sector_seek(INDEXPOS); + for (i = INDEXPOS; i < (INDEXPOS + 10); i++) { + printm(M_INFO, "Reading fat sector %lu\n", i); + cdutil->read_sector(&fat[2048 * (i - INDEXPOS)], MODE_2_FORM_1); + } + + memcpy(key, fat + 0x4f00, 256); + + printm(M_INFO, "Decrypting.\n"); + for (i = 0; i < 20480; i++) { + fat[i] ^= key[i % 256]; + } + + indexer = 0; + for (j = 4; j < 20480; j += 4) { + unsigned char m, s, f; + m = fat[j]; + s = fat[j + 1]; + f = fat[j + 2]; + index_tab[indexer].address = cdutil->from_MSF(m, s, f); + if (m || s || f) { + index_tab[indexer].index = j / 4; + index_tab[indexer].flags = fat[j + 3]; + printm(M_INFO, "Found a quite valid index: number %4lu, address %6lu - flags = %02x\n", + indexer, index_tab[indexer].address, fat[j + 3]); + indexer++; + if (indexer == nb_records) + break; + } else { + printm(M_WARNING, "Ignored invalid index chunk number %4lu\n", j / 4); + } + } + printm(M_STATUS, "Index file generation complete.\n\n"); + index_tab[indexer].address = f_iso->GetSize() / 2352; + + for (i = 0; i < nb_records; i++) { + if (sequences[seq].sum == i) + seq++; + index_tab[i].type = sequences[seq].type; + if (sequences[seq].type == 0) { + printm(M_INFO, "%6lu - %02x: ignored\n", index_tab[i].address, index_tab[i].flags); + } else { + int size; + printm(M_INFO, "%6lu - %02x: ", index_tab[i].address, index_tab[i].flags); + size = index_tab[i + 1].address - index_tab[i].address; + size *= sec_sizes[index_tab[i].type]; + file_dump(index_tab[i].address, size, i, seq); + if (verbosity >= M_INFO) { + fprintf(stderr, "\n"); + } + } + } + fprintf(stderr, "\n"); +} + +void file_dump(unsigned long debut, unsigned long taille, long num, int seq) +{ + long i; + long nbsects; + String nom; + char type = sequences[seq].type; + char ptitbidule[] = "-\\|/"; + + nom = "./" + prefix + "/"; + MKDIR(nom.to_charp()); + + nom += sequences[seq].prefix + "/"; + MKDIR(nom.to_charp()); + + nom += String().set("%04ld.out", num); + + f_out = new Output(nom); + nbsects = taille / sec_sizes[type]; + if (taille % sec_sizes[type]) + nbsects++; + cdutil->sector_seek(debut); + for (i = 0; i < nbsects; i++) { + if (verbosity < M_INFO) + fprintf(stderr, " (%c)\010\010\010\010\010", ptitbidule[((tourne++) >> 8) % 4]); + cdutil->read_sector(user_data, type); + if (i != (nbsects - 1)) { + f_out->write(user_data, sec_sizes[type]); + } else { + f_out->write(user_data, taille % sec_sizes[type] ? taille % sec_sizes[type] : sec_sizes[type]); + } + } + delete f_out; + f_out = 0; + printm(M_BARE, " (*) Dumped file number %4ld - type \"" + sequences[seq].name + "\" \r", num); +} +CODE_ENDS |