From d951e169f5f4e82590b36b1e703a09e71da1fdd1 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Sat, 28 Jun 2008 16:49:46 +0000 Subject: Rename jz4740 tools + add some new ones git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17840 a1c6a512-1295-4272-9138-f99709370657 --- utils/jz4740_tools/HXFsplit.c | 304 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100755 utils/jz4740_tools/HXFsplit.c (limited to 'utils/jz4740_tools/HXFsplit.c') diff --git a/utils/jz4740_tools/HXFsplit.c b/utils/jz4740_tools/HXFsplit.c new file mode 100755 index 0000000..ede2217 --- /dev/null +++ b/utils/jz4740_tools/HXFsplit.c @@ -0,0 +1,304 @@ +/* +Made by Maurus Cuelenaere +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION "0.2" + +struct header{ + char main_header[20]; + unsigned int size; + unsigned int checksum; + unsigned int unknown; + char other_header[32]; +}; + +static char* basepath(char* path) +{ + static char tmp[255]; + char *ptr, *ptr2, *ptr3; + ptr = path; + ptr2 = (char*)tmp; +#ifdef _WIN32 + ptr3 = strrchr(path, 0x5C); +#else + ptr3 = strrchr(path, 0x2F); +#endif + while((int)ptr < (int)ptr3) + { + *ptr2 = *ptr; + ptr++; + ptr2++; + } +#ifdef _WIN32 + *ptr2 = 0x5C; +#else + *ptr2 = 0x2F; +#endif + *ptr2++; + *ptr2 = 0; + return (char*)tmp; +} + +#ifndef _WIN32 +static void replace(char* str) +{ + char *ptr = str; + while(*ptr != 0) + { + if(*ptr == 0x5C) /* \ */ + *ptr = 0x2F; /* / */ + ptr++; + } +} +#endif + +static unsigned int le2int(unsigned char* buf) +{ + unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + + return res; +} + +#ifdef _WIN32 + #define PATH_SEPARATOR '\\' +#else + #define PATH_SEPARATOR '/' +#endif + +static unsigned int __mkdir(const char *path) +{ + char opath[256]; + char *p; + size_t len; + + strncpy(opath, path, sizeof(opath)); + len = strlen(opath); + if(opath[len - 1] == PATH_SEPARATOR) + opath[len - 1] = '\0'; + for(p = opath; *p; p++) + if(*p == PATH_SEPARATOR) + { + *p = '\0'; + if(access(opath, F_OK)) +#ifdef _WIN32 + mkdir(opath); +#else + mkdir(opath, S_IRWXU); +#endif + *p = PATH_SEPARATOR; + } + if(access(opath, F_OK)) +#ifdef _WIN32 + return mkdir(opath); +#else + return mkdir(opath, S_IRWXU); +#endif + else + return -1; +} + +#if 0 +static bool dir_exists(const char *dir) +{ + struct stat buf; + memset(&buf, 0, sizeof(struct stat)); + printf("start: %s\n", dir); + char *dir_cpy = (char*)malloc(strlen(dir)); + strcpy(dir_cpy, dir); + printf("%s\n", dir_cpy); + int tmp = (int)dir_cpy; + while(*dir_cpy != 0) + { + dir_cpy++; + if(*dir_cpy == PATH_SEPARATOR && *(dir_cpy+1) == 0) + *dir_cpy = 0; + } + printf("while_done\n"); + dir_cpy = (char*)tmp; + printf("statting %s...\n", dir_cpy); + tmp = stat(dir_cpy, &buf); + printf("chk_dir(%s) = %d\n", dir_cpy, tmp); + free(dir_cpy); + return tmp == 0; +} +#endif + +static bool file_exists(const char *file) +{ + struct stat buf; + return stat(file, &buf) == 0; +} + + +static int split_hxf(const unsigned char* infile, unsigned int size, const char* outpath) +{ + FILE *outfile; + char *filename; + unsigned int filenamesize, filesize; + while(size > 0) + { + filenamesize = le2int((unsigned char*)infile); + infile += 4; + size -= 4; + if(size > 0) + { + filename = (char*)calloc(1, filenamesize+1+strlen(outpath)); + memcpy(filename, outpath, strlen(outpath)); + memcpy(&filename[strlen(outpath)], infile, filenamesize); +#ifndef _WIN32 + replace(filename); +#endif + infile += filenamesize + 1; /* + padding */ + size -= filenamesize + 1; + + filesize = le2int((unsigned char*)infile); + infile += 4; + size -= 4; +#if 0 + if(!dir_exists(basepath(filename))) +#endif + { + printf("[INFO] %s\n", basepath(filename)); + if(__mkdir(basepath(filename)) != 0) + { +#if 0 + fprintf(stderr, "[ERR] Error creating directory %s\n", basepath(filename)); + return -3; +#endif + } + } + + if(!file_exists(filename)) + { + printf("[INFO] %s: %d bytes\n", filename, filesize); + if((outfile = fopen(filename, "wb")) == NULL) + { + fprintf(stderr, "[ERR] Error opening file %s\n", filename); + return -1; + } + if(filesize>0) + { + if(fwrite(infile, filesize, 1, outfile) != 1) + { + fclose(outfile); + fprintf(stderr, "[ERR] Error writing to file %s\n", filename); + return -2; + } + } + fclose(outfile); + } + + infile += filesize; + size -= filesize; + } + } + return 0; +} + +static void print_usage(void) +{ +#ifdef _WIN32 + fprintf(stderr, "Usage: hxfsplit.exe [FW] [OUTPUT_DIR]\n\n"); + fprintf(stderr, "Example: hxfsplit.exe VX747.HXF VX747_extracted\\\n\n"); +#else + fprintf(stderr, "Usage: HXFsplit [FW] [OUTPUT_DIR]\n\n"); + fprintf(stderr, "Example: HXFsplit VX747.HXF VX747_extracted/\n\n"); +#endif +} + +int main(int argc, char *argv[]) +{ + FILE *infile; + struct header hdr; + unsigned char *inbuffer; + + fprintf(stderr, "HXFsplit v" VERSION " - (C) 2008 Maurus Cuelenaere\n"); + fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n"); + fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); + + if(argc != 3) + { + print_usage(); + return 1; + } + +#ifdef _WIN32 + if(strcmp((char*)(argv[2]+strlen(argv[2])-1), "\\") != 0) + { + fprintf(stderr, "[ERR] Output path must end with a \\\n"); +#else + if(strcmp((char*)(argv[2]+strlen(argv[2])-1), "/") != 0) + { + fprintf(stderr, "[ERR] Output path must end with a /\n"); +#endif + return 2; + } + + if((infile = fopen(argv[1], "rb")) == NULL) + { + fprintf(stderr, "[ERR] Cannot open %s\n", argv[1]); + return 3; + } + + if((inbuffer = (unsigned char*)malloc(sizeof(struct header))) == NULL) + { + fclose(infile); + fprintf(stderr, "[ERR] Error allocating %d bytes buffer\n", sizeof(struct header)); + return 4; + } + + if(fread(inbuffer, sizeof(struct header), 1, infile) != 1) + { + fclose(infile); + fprintf(stderr, "Cannot read header of %s\n", argv[1]); + return 5; + } + + memcpy(hdr.main_header, inbuffer, 20); + hdr.size = le2int(&inbuffer[20]); + hdr.checksum = le2int(&inbuffer[24]); + hdr.unknown = le2int(&inbuffer[28]); + memcpy(hdr.other_header, &inbuffer[32], 32); + free(inbuffer); + + if(strcmp(hdr.other_header, "Chinachip PMP firmware V1.0") != 0) + { + fclose(infile); + fprintf(stderr, "[ERR] Header doesn't match\n"); + return 6; + } + + if((inbuffer = (unsigned char*)malloc(hdr.size)) == NULL) + { + fclose(infile); + fprintf(stderr, "[ERR] Error allocating %d bytes buffer\n", hdr.size); + return 7; + } + + fseek(infile, sizeof(struct header), SEEK_SET); + + if(fread(inbuffer, hdr.size-sizeof(struct header), 1, infile) != 1) + { + fclose(infile); + free(inbuffer); + fprintf(stderr, "[ERR] Cannot read file in buffer\n"); + return 8; + } + + fclose(infile); + + split_hxf(inbuffer, hdr.size-sizeof(struct header), argv[2]); + + free(inbuffer); + + return 0; +} -- cgit v1.1