diff options
Diffstat (limited to 'VP/main_dump.cpp')
| -rw-r--r-- | VP/main_dump.cpp | 290 | 
1 files changed, 290 insertions, 0 deletions
diff --git a/VP/main_dump.cpp b/VP/main_dump.cpp new file mode 100644 index 0000000..cf6197d --- /dev/null +++ b/VP/main_dump.cpp @@ -0,0 +1,290 @@ +/* + * 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 "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, *prefix; +unsigned long iso_size; +unsigned int nb_records, nb_seqs = 0; +struct t_sequence sequences[1000]; + +long check_iso(FILE * f_iso); +void read_files(FILE * f_iso); +void file_dump(FILE * f_iso, unsigned long debut, unsigned long taille, long num, int seq); +int process_def_file(FILE * f_def); + +unsigned char user_data[2352]; + +int main(int argc, char **argv) +{ +    FILE * f_def, * f_iso; +     +    verbosity = 3; +     +    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]); +	exit(-1); +    } + +    printm(M_STATUS, "Processing file %s...\n", argv[1]); + +    if (!(f_def = fopen(argv[1], "r"))) { +	printm(M_ERROR, "Unable to open the definition file \"%s\"...\n", argv[1]); +	exit(-1); +    } + +    if (process_def_file(f_def)) { +	fclose(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 = fopen(iso_filename, "r"))) { +	printm(M_ERROR, "Unable to open the iso file \"%s\"...\n", iso_filename); +	exit(-1); +    } + +    if (check_iso(f_iso)) { +	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); +    } +    printm(M_STATUS, "Entering files read sequence\n"); +    read_files(f_iso); +    fclose(f_iso); +    exit(0); +} + +/* + * Ugly but working... for now  + */ +int process_def_file(FILE * f_def) +{ +    char t[1024], *p; +    unsigned int n, sum = 0; + +    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 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(FILE * 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; +} + +void read_files(FILE * f_iso) +{ +    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; + +    unsigned char fat[32768]; + +#define INDEXPOS 24 + +    sector_seek(f_iso, INDEXPOS); +    for (i = INDEXPOS; i < (INDEXPOS + 16); i++) { +	printm(M_INFO, "Reading fat sector %lu\n", i); +	read_sector(f_iso, &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].type == 0) { +	    printm(M_INFO, "%6lu (%10lu): ignored\n", index_tab[i].address, index_tab[i].size); +	} else { +	    printm(M_INFO, "%6lu (%10lu): ", index_tab[i].address, index_tab[i].size); +	    file_dump(f_iso, index_tab[i].address, index_tab[i].size, i, seq); +	    if (verbosity >= M_INFO) { +		fprintf(stderr, "\n"); +	    } +	} +    } +    fprintf(stderr, "\n"); +} + +void file_dump(FILE * f_iso, unsigned long debut, unsigned long taille, long num, int seq) +{ +    long i; +    long nbsects; +    char nom[1000] = ""; +    char *extention = ".out"; +    char nom_t[1000] = ""; +    int f_out; +    char type = sequences[seq].type; +    char ptitbidule[] = "-\\|/"; +     +    sprintf(nom_t, "%ld", num); + +    strcat(nom, "./"); + +    strcat(nom, prefix); +    strcat(nom, "/"); +    MKDIR(nom); + +    strcat(nom, sequences[seq].prefix); +    strcat(nom, "/"); +    MKDIR(nom); + +    if (num < 10) +	strcat(nom, "0"); +    if (num < 100) +	strcat(nom, "0"); +    if (num < 1000) +	strcat(nom, "0"); +    strcat(nom, nom_t); + +    strcat(nom, extention); +    f_out = open(nom, O_WRONLY | O_CREAT | O_TRUNC, 00644); +    nbsects = taille / sec_sizes[type]; +    if (taille % sec_sizes[type]) +	nbsects++; +    sector_seek(f_iso, debut); +    for (i = 0; i < nbsects; i++) { +	if (verbosity < M_INFO)  +	    fprintf(stderr, "  (%c)\010\010\010\010\010", ptitbidule[((tourne++) >> 8) % 4]); +	read_sector(f_iso, user_data, type); +	if (i != (nbsects - 1)) { +	    write(f_out, user_data, sec_sizes[type]); +	} else { +	    write(f_out, user_data, taille % sec_sizes[type] ? taille % sec_sizes[type] : sec_sizes[type]); +	} +    } +    close(f_out); +    fprintf(stderr, "  (*) Dumped file number %4ld - type \"%s\"           \r", num, sequences[seq].name); +}  | 
