Difference between revisions of "User:Magicus/Magicus's Tools/Parse-channel.c"
Jump to navigation
Jump to search
(Replace with the right file (it's late! :)), and add some instructions) |
|||
Line 1: | Line 1: | ||
+ | '''Put this file in the same directory as a compiled version of [[Segher's Wii.git]] tools, since it depends on them.''' | ||
+ | |||
+ | : Sorry for the beta status, it's 2 am and I need to get some sleep ;-) but I thought it was better I released what I've done so far. Feel free to improve it. [[User:Magicus|Magicus]] 17:00, 1 March 2008 (PST) | ||
+ | |||
<pre> | <pre> | ||
− | // parse- | + | // parse-u8.c |
// Compile with: | // Compile with: | ||
− | // gcc -g -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -Wall -W -O2 -c -o parse- | + | // gcc -g -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -Wall -W -O2 -c -o parse-u8.o parse-u8.c |
− | // gcc -g -lcrypto parse- | + | // gcc -g -lcrypto parse-u8.o tools.o bn.o ec.o -o parse-u8 |
// The other files are from segher's git repository, created by his Makefile. | // The other files are from segher's git repository, created by his Makefile. | ||
// Copyright 2008 Magicus <magicus@gmail.com> | // Copyright 2008 Magicus <magicus@gmail.com> | ||
− | |||
− | |||
− | |||
// Licensed under the terms of the GNU GPL, version 2 | // Licensed under the terms of the GNU GPL, version 2 | ||
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | ||
− | // Version | + | // Version 0.5 Beta version, just lists contents, doesn't yet extract files. |
− | |||
− | |||
+ | #include <sys/stat.h> | ||
+ | #include <sys/types.h> | ||
+ | |||
#include <string.h> | #include <string.h> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <stdio.h> | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
#include "tools.h" | #include "tools.h" | ||
Line 31: | Line 34: | ||
return (p[0] << 8) | p[1]; | return (p[0] << 8) | p[1]; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
static FILE *fp; | static FILE *fp; | ||
− | static char | + | static char *outdir = "OUTDIR"; |
− | + | typedef struct | |
− | + | { | |
− | + | u16 type; | |
+ | u16 name_offset; | ||
+ | u32 data_offset; // == absolut offset från U.8- headerns början | ||
+ | u32 size; // last included file num for directories | ||
+ | } U8_node; | ||
− | typedef struct | + | typedef struct |
− | + | { | |
− | + | u32 tag; // 0x55AA382D "U.8-" | |
− | + | u32 rootnode_offset; // offset to root_node, always 0x20. | |
− | + | u32 header_size; // size of header from root_node to end of string table. | |
− | + | u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40. | |
− | + | u8 zeroes[16]; | |
− | + | } U8_archive_header; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | u8 | ||
− | } | ||
+ | /* | ||
static void write_part(void* data, size_t size, char* name) | static void write_part(void* data, size_t size, char* name) | ||
{ | { | ||
Line 96: | Line 63: | ||
snprintf(filename, sizeof(filename), "%s_%s.bin", gamename, name); | snprintf(filename, sizeof(filename), "%s_%s.bin", gamename, name); | ||
− | filename[ | + | filename[127] = '\0'; |
out = fopen(filename, "wb"); | out = fopen(filename, "wb"); | ||
fwrite(data, 1, size, out); | fwrite(data, 1, size, out); | ||
fclose(out); | fclose(out); | ||
} | } | ||
+ | */ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | static void do_U8_archive(void) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | static | ||
{ | { | ||
− | + | U8_archive_header header; | |
− | + | U8_node root_node; | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
u32 tag; | u32 tag; | ||
− | u32 | + | u32 num_nodes; |
− | u32 | + | U8_node* nodes; |
+ | u8* string_table; | ||
+ | size_t rest_size; | ||
+ | unsigned int i; | ||
+ | u32 data_offset; | ||
− | + | fread(&header, 1, sizeof header, fp); | |
− | + | tag = be32((u8*) &header.tag); | |
− | + | if (tag != 0x55AA382D) { | |
− | + | ERROR("No U8 tag"); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | tag = be32((u8*) &header | ||
− | if (tag != | ||
− | ERROR("No | ||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | fread(&root_node, 1, sizeof(root_node), fp); | |
− | + | num_nodes = be32((u8*) &root_node.size) - 1; | |
− | + | printf("Number of files: %d\n", num_nodes); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | nodes = malloc(sizeof(U8_node) * (num_nodes)); | |
− | + | fread(nodes, 1, num_nodes * sizeof(U8_node), fp); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | data_offset = be32((u8*) &header.data_offset); | |
− | + | rest_size = data_offset - sizeof(header) - num_nodes*sizeof(U8_node); | |
− | |||
− | |||
− | + | string_table = malloc(rest_size); | |
+ | fread(string_table, 1, rest_size, fp); | ||
+ | |||
+ | for (i = 0; i < num_nodes; i++) { | ||
+ | U8_node* node = &nodes[i]; | ||
+ | u16 type = be16((u8*)&node->type); | ||
+ | u16 name_offset = be16((u8*)&node->name_offset); | ||
+ | u32 data_offset = be32((u8*)&node->data_offset); | ||
+ | u32 size = be32((u8*)&node->size); | ||
+ | char* name = (char*) &string_table[name_offset]; | ||
+ | char* premarker; | ||
+ | char* postmarker; | ||
+ | |||
+ | if (type == 0x0100) { | ||
+ | premarker = ""; | ||
+ | postmarker = "/"; | ||
+ | } else { | ||
+ | premarker = " "; | ||
+ | postmarker = ""; | ||
} | } | ||
+ | |||
+ | printf("%s%s%s (%d) offset: %x\n", premarker, name, postmarker, size, data_offset); | ||
} | } | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||
{ | { | ||
− | if (argc != 2) { | + | if (argc == 3) { |
− | ERROR("Usage: parse- | + | outdir = argv[2]; |
+ | } else if (argc != 2) { | ||
+ | ERROR("Usage: parse-u8 <file> [<outdir>]"); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
fp = fopen(argv[1], "rb"); | fp = fopen(argv[1], "rb"); | ||
− | + | // mkdir(outdir, 0777); | |
− | + | // chdir(outdir); | |
− | + | ||
− | + | do_U8_archive(); | |
− | |||
− | |||
fclose(fp); | fclose(fp); |
Revision as of 03:00, 2 March 2008
Put this file in the same directory as a compiled version of Segher's Wii.git tools, since it depends on them.
- Sorry for the beta status, it's 2 am and I need to get some sleep ;-) but I thought it was better I released what I've done so far. Feel free to improve it. Magicus 17:00, 1 March 2008 (PST)
// parse-u8.c // Compile with: // gcc -g -DLARGE_FILES -D_FILE_OFFSET_BITS=64 -Wall -W -O2 -c -o parse-u8.o parse-u8.c // gcc -g -lcrypto parse-u8.o tools.o bn.o ec.o -o parse-u8 // The other files are from segher's git repository, created by his Makefile. // Copyright 2008 Magicus <magicus@gmail.com> // Licensed under the terms of the GNU GPL, version 2 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt // Version 0.5 Beta version, just lists contents, doesn't yet extract files. #include <sys/stat.h> #include <sys/types.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include "tools.h" #define ERROR(s) do { fprintf(stderr, s "\n"); exit(1); } while (0) // FIXME: this should really move to tools.c u16 be16(u8 *p) { return (p[0] << 8) | p[1]; } static FILE *fp; static char *outdir = "OUTDIR"; typedef struct { u16 type; u16 name_offset; u32 data_offset; // == absolut offset från U.8- headerns början u32 size; // last included file num for directories } U8_node; typedef struct { u32 tag; // 0x55AA382D "U.8-" u32 rootnode_offset; // offset to root_node, always 0x20. u32 header_size; // size of header from root_node to end of string table. u32 data_offset; // offset to data -- this is rootnode_offset + header_size, aligned to 0x40. u8 zeroes[16]; } U8_archive_header; /* static void write_part(void* data, size_t size, char* name) { FILE *out; char filename[128]; snprintf(filename, sizeof(filename), "%s_%s.bin", gamename, name); filename[127] = '\0'; out = fopen(filename, "wb"); fwrite(data, 1, size, out); fclose(out); } */ static void do_U8_archive(void) { U8_archive_header header; U8_node root_node; u32 tag; u32 num_nodes; U8_node* nodes; u8* string_table; size_t rest_size; unsigned int i; u32 data_offset; fread(&header, 1, sizeof header, fp); tag = be32((u8*) &header.tag); if (tag != 0x55AA382D) { ERROR("No U8 tag"); } fread(&root_node, 1, sizeof(root_node), fp); num_nodes = be32((u8*) &root_node.size) - 1; printf("Number of files: %d\n", num_nodes); nodes = malloc(sizeof(U8_node) * (num_nodes)); fread(nodes, 1, num_nodes * sizeof(U8_node), fp); data_offset = be32((u8*) &header.data_offset); rest_size = data_offset - sizeof(header) - num_nodes*sizeof(U8_node); string_table = malloc(rest_size); fread(string_table, 1, rest_size, fp); for (i = 0; i < num_nodes; i++) { U8_node* node = &nodes[i]; u16 type = be16((u8*)&node->type); u16 name_offset = be16((u8*)&node->name_offset); u32 data_offset = be32((u8*)&node->data_offset); u32 size = be32((u8*)&node->size); char* name = (char*) &string_table[name_offset]; char* premarker; char* postmarker; if (type == 0x0100) { premarker = ""; postmarker = "/"; } else { premarker = " "; postmarker = ""; } printf("%s%s%s (%d) offset: %x\n", premarker, name, postmarker, size, data_offset); } } int main(int argc, char **argv) { if (argc == 3) { outdir = argv[2]; } else if (argc != 2) { ERROR("Usage: parse-u8 <file> [<outdir>]"); } fp = fopen(argv[1], "rb"); // mkdir(outdir, 0777); // chdir(outdir); do_U8_archive(); fclose(fp); return 0; }