Improve English in the codebuster manual entry.
[kugel-rb.git] / utils / jz4740_tools / HXFmerge.c
blob6b6c62505e13ed1519f72381c4b7b030076dbe57
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Maurus Cuelenaere
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29 #include <stdbool.h>
30 #include <dirent.h>
32 #define VERSION "0.2"
34 static unsigned char* int2le(unsigned int val)
36 static unsigned char addr[4];
37 addr[0] = val & 0xff;
38 addr[1] = (val >> 8) & 0xff;
39 addr[2] = (val >> 16) & 0xff;
40 addr[3] = (val >> 24) & 0xff;
41 return addr;
44 static unsigned int le2int(unsigned char* buf)
46 unsigned int res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
48 return res;
51 #ifdef _WIN32
52 #define PATH_SEPARATOR "\\"
53 #else
54 #define PATH_SEPARATOR "/"
55 #endif
57 #ifndef _WIN32
59 #define MIN(a, b) (a > b ? b : a)
60 static char* replace(char* str)
62 static char tmp[255];
63 memcpy(tmp, str, MIN(strlen(str), 255));
64 char *ptr = tmp;
65 while(*ptr != 0)
67 if(*ptr == 0x2F) /* /*/
68 *ptr = 0x5C; /* \ */
69 ptr++;
71 return tmp;
73 #endif
75 static bool is_dir(const char* name1, const char* name2)
77 char *name;
78 DIR *directory;
79 name = (char*)malloc(strlen(name1)+strlen(name2)+1);
80 strcpy(name, name1);
81 strcat(name, name2);
82 directory = opendir(name);
83 free(name);
84 if(directory)
86 closedir(directory);
87 return true;
89 else
90 return false;
93 unsigned int _filesize(FILE* fd)
95 unsigned int tmp, oldpos;
96 oldpos = ftell(fd);
97 fseek(fd, 0, SEEK_END);
98 tmp = ftell(fd);
99 fseek(fd, oldpos, SEEK_SET);
100 return tmp;
102 #define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
104 closedir(indir_handle); \
105 if(filesize > 0) \
106 free(buffer); \
107 fprintf(stderr, "[ERR] Error writing to file\n"); \
108 return; \
110 static void merge_hxf(const char* indir, FILE* outfile, const char* add)
112 DIR *indir_handle;
113 struct dirent *dirs;
114 char dir[255];
115 strcpy(dir, indir);
116 strcat(dir, add);
118 if((indir_handle = opendir(dir)) == NULL)
120 fprintf(stderr, "[ERR] Error opening dir %s\n", indir);
121 return;
124 while((dirs = readdir(indir_handle)) != NULL)
126 if(strcmp(dirs->d_name, "..") != 0 &&
127 strcmp(dirs->d_name, ".") != 0)
129 fprintf(stderr, "[INFO] %s\%s\n", add, dirs->d_name);
130 if(is_dir(dir, dirs->d_name))
132 char dir2[255];
133 strcpy(dir2, add);
134 strcat(dir2, dirs->d_name);
135 strcat(dir2, PATH_SEPARATOR);
136 merge_hxf(indir, outfile, dir2);
138 else
140 FILE *filehandle;
141 unsigned char *buffer;
142 char file[255];
143 unsigned int filesize;
144 strcpy(file, dir);
145 strcat(file, dirs->d_name);
146 if((filehandle = fopen(file, "rb")) == NULL)
148 fprintf(stderr, "[ERR] Cannot open %s\n", file);
149 closedir(indir_handle);
150 return;
152 filesize = _filesize(filehandle);
153 if(filesize > 0)
155 buffer = (unsigned char*)malloc(filesize);
156 if(buffer == NULL)
158 fclose(filehandle);
159 closedir(indir_handle);
160 fprintf(stderr, "[ERR] Cannot allocate memory\n");
161 return;
163 if(fread(buffer, filesize, 1, filehandle) != 1)
165 fclose(filehandle);
166 closedir(indir_handle);
167 free(buffer);
168 fprintf(stderr, "[ERR] Cannot read from %s%s%s\n", add, PATH_SEPARATOR, dirs->d_name);
169 return;
172 fclose(filehandle);
174 if(strlen(add)>0)
176 #ifdef _DIRENT_HAVE_D_NAMLEN
177 WRITE(int2le(dirs->d_namlen+strlen(add)), 4);
178 #else
179 WRITE(int2le(strlen(dirs->d_name)+strlen(add)), 4);
180 #endif
181 #ifndef _WIN32
182 WRITE(replace((char*)add), strlen(add)-1);
183 #else
184 WRITE(add, strlen(add)-1);
185 #endif
186 WRITE(PATH_SEPARATOR, 1);
187 #ifdef _DIRENT_HAVE_D_NAMLEN
188 WRITE(dirs->d_name, dirs->d_namlen);
189 #else
190 WRITE(dirs->d_name, strlen(dirs->d_name));
191 #endif
193 else
195 #ifdef _DIRENT_HAVE_D_NAMLEN
196 WRITE(int2le(dirs->d_namlen), 4);
197 WRITE(dirs->d_name, dirs->d_namlen);
198 #else
199 WRITE(int2le(strlen(dirs->d_name)), 4);
200 WRITE(dirs->d_name, strlen(dirs->d_name));
201 #endif
203 WRITE(int2le(filesize), 4);
204 if(filesize>0)
206 WRITE(buffer, filesize);
207 free(buffer);
212 closedir(indir_handle);
215 static void print_usage(void)
217 #ifdef _WIN32
218 fprintf(stderr, "Usage: hxfmerge.exe [INPUT_DIR] [FW]\n\n");
219 fprintf(stderr, "Example: hxfmerge.exe VX747_extracted\\ VX747.HXF\n\n");
220 #else
221 fprintf(stderr, "Usage: HXFmerge [INPUT_DIR] [FW]\n\n");
222 fprintf(stderr, "Example: HXFmerge VX747_extracted/ VX747.HXF\n\n");
223 #endif
226 static int checksum(FILE *file)
228 int oldpos = ftell(file);
229 int ret=0, i, filesize = _filesize(file)-0x40;
230 unsigned char *buf;
232 buf = (unsigned char*)malloc(filesize);
234 if(buf == NULL)
236 fseek(file, oldpos, SEEK_SET);
237 fprintf(stderr, "[ERR] Error while allocating memory\n");
238 return 0;
241 fseek(file, 0x40, SEEK_SET);
242 if(fread(buf, filesize, 1, file) != 1)
244 free(buf);
245 fseek(file, oldpos, SEEK_SET);
246 fprintf(stderr, "[ERR] Error while reading from file\n");
247 return 0;
250 fprintf(stderr, "[INFO] Computing checksum...");
252 for(i = 0; i < filesize; i+=4)
253 ret += le2int(&buf[i]);
255 free(buf);
256 fseek(file, oldpos, SEEK_SET);
258 fprintf(stderr, " Done!\n");
259 return ret;
262 int main(int argc, char *argv[])
264 FILE *outfile;
266 fprintf(stderr, "HXFmerge v" VERSION " - (C) 2008 Maurus Cuelenaere\n");
267 fprintf(stderr, "This is free software; see the source for copying conditions. There is NO\n");
268 fprintf(stderr, "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
270 if(argc != 3)
272 print_usage();
273 return 1;
276 #ifdef _WIN32
277 if(strcmp((char*)(argv[1]+strlen(argv[1])-1), "\\") != 0)
279 fprintf(stderr, "[ERR] Input path must end with a \\\n");
280 #else
281 if(strcmp((char*)(argv[1]+strlen(argv[1])-1), "/") != 0)
283 fprintf(stderr, "[ERR] Input path must end with a /\n");
284 #endif
285 return 2;
288 if((outfile = fopen(argv[2], "wb+")) == NULL)
290 fprintf(stderr, "[ERR] Cannot open %s\n", argv[2]);
291 return 3;
294 fseek(outfile, 0x40, SEEK_SET);
296 merge_hxf(argv[1], outfile, "");
298 fflush(outfile);
300 fprintf(stderr, "[INFO] Filling header...\n");
302 #undef WRITE
303 #define WRITE(x, len) if(fwrite(x, len, 1, outfile) != 1) \
305 fprintf(stderr, "[ERR] Cannot write to %s\n", argv[1]); \
306 fclose(outfile); \
307 return 4; \
309 fflush(outfile);
310 fseek(outfile, 0, SEEK_SET);
311 WRITE("WADF0100200804111437", 20);
312 WRITE(int2le(_filesize(outfile)), 4);
313 WRITE(int2le(checksum(outfile)), 4);
314 WRITE(int2le(0), 4);
315 WRITE("Chinachip PMP firmware V1.0\0\0\0\0\0", 32);
316 fclose(outfile);
318 fprintf(stderr, "[INFO] Done!\n");
320 return 0;