From e98d732e8f400708312b67b14b32fc827468cc8f Mon Sep 17 00:00:00 2001 From: Wu Yongzheng Date: Thu, 16 Aug 2012 00:31:15 +0800 Subject: [PATCH] fix 2G limit bug --- .gitignore | 3 +- Makefile | 8 ++--- gimgch.c | 69 +++++-------------------------------------- gimgextract.c | 57 +++-------------------------------- gimgunlock.c | 80 ++++++-------------------------------------------- makefile.nmake | 27 ++++------------- util_indep.c | 63 +++++++++++++++++++++++++++++++++++++++ util_indep.h | 19 ++++++++++++ 8 files changed, 113 insertions(+), 213 deletions(-) create mode 100644 util_indep.c create mode 100644 util_indep.h diff --git a/.gitignore b/.gitignore index 1c609b8..43b7fcd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -map-*.img +*.img *.o *.obj +*.exe diff --git a/Makefile b/Makefile index 44de5f8..c23faeb 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -Wall +CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 GIMGLIB_SOURCES = gimglib.c util.c sf_typ.c sf_mps.c sf_tre.c sf_rgn.c sf_lbl.c sf_net.c sf_nod.c sf_gmp.c GIMGLIB_OBJS = $(GIMGLIB_SOURCES:.c=.o) @@ -12,11 +12,11 @@ gimgfixcmd: gimgfixcmd.o cmdlib.o $(GIMGLIB_OBJS) gimgxor: gimgxor.o -gimgunlock: gimgunlock.o +gimgunlock: gimgunlock.o util_indep.o -gimgch: gimgch.o +gimgch: gimgch.o util_indep.o -gimgextract: gimgextract.o +gimgextract: gimgextract.o util_indep.o cmdc: cmdc.o $(CC) -o $@ $< -lm diff --git a/gimgch.c b/gimgch.c index ca46ab8..a89cfd7 100644 --- a/gimgch.c +++ b/gimgch.c @@ -4,14 +4,15 @@ #include #include #include +#include "util_indep.h" struct header_struct { const char *imgpath; char subfile[16]; + off_t subfile_offset; /* abs offset */ + int subfile_size; int header_rel_offset; /* 0 if it's OF */ int header_size; - int subfile_offset; /* abs offset */ - int subfile_size; unsigned char *header; char id[4]; }; @@ -21,56 +22,6 @@ static struct header_struct *headers[MAX_HEADERS]; static int header_num = 0; -static int read_byte_at (FILE *fp, unsigned long offset) -{ - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - return getc(fp); -} - -static int read_2byte_at (FILE *fp, unsigned long offset) -{ - int n = 0; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(&n, 2, 1, fp) != 1) { - perror(NULL); - exit(1); - } - return n; -} - -static unsigned int read_4byte_at (FILE *fp, unsigned long offset) -{ - int n = 0; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(&n, 4, 1, fp) != 1) { - perror(NULL); - exit(1); - } - return n; -} - -static void read_bytes_at (FILE *fp, unsigned long offset, - unsigned char *buffer, int size) -{ - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(buffer, size, 1, fp) != 1) { - perror(NULL); - exit(1); - } -} - static void display_headers (int line_columns) { int i, ptr, bytes_pre_line; @@ -166,7 +117,7 @@ static void display_headers (int line_columns) } static int add_header(FILE *fp, const char *imgpath, const char *sf_name, - int subfile_offset, int subfile_size, int header_rel_offset) + off_t subfile_offset, int subfile_size, int header_rel_offset) { struct header_struct *header = (struct header_struct *)malloc(sizeof(struct header_struct)); @@ -195,13 +146,6 @@ static int add_header(FILE *fp, const char *imgpath, const char *sf_name, return 0; } -#define errexit(...) \ - do { \ - printf(__VA_ARGS__); \ - if (fp) \ - fclose(fp); \ - return 1; \ - } while (0) static int read_header (const char *imgpath, const char *subfile_name_pattern, int match_maximum) { @@ -223,7 +167,7 @@ static int read_header (const char *imgpath, const char *subfile_name_pattern, fatstart = read_byte_at(fp, 0x40) == 0 ? 3 : read_byte_at(fp, 0x40); if (read_4byte_at(fp, 0x40c) == 0) { // use root dir. assume it's the first file - unsigned long offset = fatstart * 512; + off_t offset = fatstart * 512; if (read_byte_at(fp, offset) != 1 || read_byte_at(fp, offset + 0x1) != ' ' || read_byte_at(fp, offset + 0x9) != ' ') @@ -240,7 +184,8 @@ static int read_header (const char *imgpath, const char *subfile_name_pattern, } for (fatcount = fatstart; fatcount < fatend; fatcount ++) { - unsigned long offset = fatcount * 512, subfile_offset, subfile_size; + off_t offset = fatcount * 512, subfile_offset; + int subfile_size; char sf_name[16]; if (read_byte_at(fp, offset) != 1) diff --git a/gimgextract.c b/gimgextract.c index 5a55e5a..a116575 100644 --- a/gimgextract.c +++ b/gimgextract.c @@ -2,57 +2,7 @@ #include #include #include - -int read_byte_at (FILE *fp, unsigned long offset) -{ - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - return getc(fp); -} - -int read_2byte_at (FILE *fp, unsigned long offset) -{ - int n = 0; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(&n, 2, 1, fp) != 1) { - perror(NULL); - exit(1); - } - return n; -} - -unsigned int read_4byte_at (FILE *fp, unsigned long offset) -{ - int n = 0; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(&n, 4, 1, fp) != 1) { - perror(NULL); - exit(1); - } - return n; -} - -void read_bytes_at (FILE *fp, unsigned long offset, unsigned char *buffer, int size) -{ - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(buffer, size, 1, fp) != 1) { - perror(NULL); - exit(1); - } -} - -#define errexit(...) do {printf(__VA_ARGS__); return 1;} while (0) +#include "util_indep.h" int main (int argc, char *argv[]) { @@ -78,7 +28,7 @@ int main (int argc, char *argv[]) fatstart = read_byte_at(infp, 0x40) == 0 ? 3 : read_byte_at(infp, 0x40); if (read_4byte_at(infp, 0x40c) == 0) { // use root dir. assume it's the first file - unsigned long offset = fatstart * 512; + off_t offset = fatstart * 512; if (read_byte_at(infp, offset) != 1 || read_byte_at(infp, offset + 0x1) != ' ' || read_byte_at(infp, offset + 0x9) != ' ') @@ -93,7 +43,8 @@ int main (int argc, char *argv[]) } for (fatcount = fatstart; fatcount < fatend; fatcount ++) { - unsigned long offset = fatcount * 512, sf_offset, sf_size; + off_t offset = fatcount * 512, sf_offset; + int sf_size; char sf_name[16]; FILE *outfp; diff --git a/gimgunlock.c b/gimgunlock.c index f4fb7be..3b294fa 100644 --- a/gimgunlock.c +++ b/gimgunlock.c @@ -2,24 +2,16 @@ #include #include #include - -#define errexit(...) do {printf(__VA_ARGS__); exit(1);} while (0) +#include "util_indep.h" struct patch_struct { - unsigned long offset; - unsigned long size; unsigned char *data; struct patch_struct *next; + off_t offset; + unsigned long size; }; -void hexdump (const unsigned char *data, int size) -{ - while (size -- > 0) - printf("%02x", *(data ++)); - printf("\n"); -} - void unlockml (unsigned char *dst, const unsigned char *src, int size, unsigned int key) { @@ -53,8 +45,7 @@ struct patch_struct *prepend_patch (struct patch_struct *patch_list, unsigned lo { struct patch_struct *new_patch = (struct patch_struct *)malloc(sizeof(struct patch_struct) + size); - if (new_patch == NULL) - errexit("out of memory\n"); + assert(new_patch != NULL); memset(new_patch, 0, sizeof(struct patch_struct) + size); new_patch->size = size; new_patch->data = (unsigned char *)new_patch + sizeof(struct patch_struct); @@ -62,61 +53,8 @@ struct patch_struct *prepend_patch (struct patch_struct *patch_list, unsigned lo return new_patch; } -unsigned int read_byte_at (FILE *fp, unsigned long offset) -{ - int c; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - c = getc(fp); - if (c == EOF) - errexit("Unexpected EOF\n"); - return c; -} - -unsigned int read_2byte_at (FILE *fp, unsigned long offset) -{ - unsigned char buff[2]; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(&buff, 2, 1, fp) != 1) { - perror(NULL); - exit(1); - } - return (buff[1] << 8) | buff[0]; -} - -unsigned int read_4byte_at (FILE *fp, unsigned long offset) -{ - unsigned char buff[4]; - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(&buff, 4, 1, fp) != 1) { - perror(NULL); - exit(1); - } - return (buff[3] << 24) | (buff[2] << 16) | (buff[1] << 8) | buff[0]; -} - -void read_bytes_at (FILE *fp, unsigned long offset, unsigned char *buffer, int size) -{ - if (fseek(fp, offset, SEEK_SET)) { - perror(NULL); - exit(1); - } - if (fread(buffer, size, 1, fp) != 1) { - perror(NULL); - exit(1); - } -} - struct patch_struct *unlock_tre (FILE *fp, struct patch_struct *patch, - unsigned long base, unsigned long header) + off_t base, off_t header) { unsigned int key, mloff, mlsize; unsigned char encml[64]; /* at most 16 levels */ @@ -169,7 +107,7 @@ struct patch_struct *create_patch (FILE *fp) fatstart = read_byte_at(fp, 0x40) == 0 ? 3 : read_byte_at(fp, 0x40); if (read_4byte_at(fp, 0x40c) == 0) { // use root dir. assume it's the first file - unsigned long offset = fatstart * 512; + off_t offset = fatstart * 512; if (read_byte_at(fp, offset) != 1 || read_byte_at(fp, offset + 0x1) != ' ' || read_byte_at(fp, offset + 0x9) != ' ') @@ -186,7 +124,7 @@ struct patch_struct *create_patch (FILE *fp) } for (fatcount = fatstart; fatcount < fatend; fatcount ++) { - unsigned long offset = fatcount * 512; + off_t offset = fatcount * 512; char subfile_name[16]; if (read_byte_at(fp, offset) != 1) @@ -205,7 +143,7 @@ struct patch_struct *create_patch (FILE *fp) if (read_byte_at(fp, offset + 0x9) == 'G' && read_byte_at(fp, offset + 0xa) == 'M' && read_byte_at(fp, offset + 0xb) == 'P') { - unsigned long tre_offset; + off_t tre_offset; offset = read_2byte_at(fp, offset + 0x20) * block_size; if (read_byte_at(fp, offset + 0x2) != 'G' || read_byte_at(fp, offset + 0x9) != 'G' || @@ -262,7 +200,7 @@ void apply_patch (FILE *fp, struct patch_struct *patch_list) struct patch_struct *patch; for (patch = patch_list; patch != NULL; patch = patch->next) { - if (fseek(fp, patch->offset, SEEK_SET)) { + if (myfseek64(fp, patch->offset)) { perror(NULL); return; } diff --git a/makefile.nmake b/makefile.nmake index 14c400c..4eb5e9c 100644 --- a/makefile.nmake +++ b/makefile.nmake @@ -10,31 +10,14 @@ gimgxor.exe: gimgxor.c $(CC) $(CFLAGS) gimgxor.c gimgunlock.exe: gimgunlock.c - $(CC) $(CFLAGS) gimgunlock.c + $(CC) $(CFLAGS) gimgunlock.c util_indep.c -gimgdh.exe: gimgdh.c - $(CC) $(CFLAGS) gimgdh.c - -gimginfo.obj: - $(CC) $(CFLAGS) /c gimginfo.c - -gimglib.obj: - $(CC) $(CFLAGS) /c gimglib.c - -util.obj: - $(CC) $(CFLAGS) /c util.c - -sf_tre.obj: - $(CC) $(CFLAGS) /c sf_tre.c - -sf_typ.obj: - $(CC) $(CFLAGS) /c sf_typ.c - -sf_mps.obj: - $(CC) $(CFLAGS) /c sf_mps.c +gimgch.exe: gimgch.c + $(CC) $(CFLAGS) gimgch.c util_indep.c clean: -del /F $(OBJS) gimginfo.exe -del /F gimgxor.exe gimgxor.obj -del /F gimgunlock.exe gimgunlock.obj - -del /F gimgdh.exe gimgdh.obj + -del /F gimgch.exe gimgch.obj + -del /F util_indep.obj diff --git a/util_indep.c b/util_indep.c new file mode 100644 index 0000000..2443a3a --- /dev/null +++ b/util_indep.c @@ -0,0 +1,63 @@ +#include +#include +#include "util_indep.h" + +void hexdump (const unsigned char *data, int size) +{ + while (size -- > 0) + printf("%02x", *(data ++)); + printf("\n"); +} + +unsigned int read_byte_at (FILE *fp, off_t offset) +{ + int c; + if (myfseek64(fp, offset)) { + perror(NULL); + exit(1); + } + c = getc(fp); + if (c == EOF) + errexit("Unexpected EOF\n"); + return c; +} + +unsigned int read_2byte_at (FILE *fp, off_t offset) +{ + unsigned char buff[2]; + if (myfseek64(fp, offset)) { + perror(NULL); + exit(1); + } + if (fread(&buff, 2, 1, fp) != 1) { + perror(NULL); + exit(1); + } + return (buff[1] << 8) | buff[0]; +} + +unsigned int read_4byte_at (FILE *fp, off_t offset) +{ + unsigned char buff[4]; + if (myfseek64(fp, offset)) { + perror(NULL); + exit(1); + } + if (fread(&buff, 4, 1, fp) != 1) { + perror(NULL); + exit(1); + } + return (buff[3] << 24) | (buff[2] << 16) | (buff[1] << 8) | buff[0]; +} + +void read_bytes_at (FILE *fp, off_t offset, unsigned char *buffer, int size) +{ + if (myfseek64(fp, offset)) { + perror(NULL); + exit(1); + } + if (fread(buffer, size, 1, fp) != 1) { + perror(NULL); + exit(1); + } +} diff --git a/util_indep.h b/util_indep.h new file mode 100644 index 0000000..b2976fd --- /dev/null +++ b/util_indep.h @@ -0,0 +1,19 @@ +#ifndef UTILS_H +#define UTILS_H + +#define errexit(...) do {printf(__VA_ARGS__); exit(1);} while (0) + +#if defined(_MSC_VER) || defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64) +typedef __int64 off_t; +#define myfseek64(fp,pos) _fseeki64(fp, pos, SEEK_SET) +#else +#define myfseek64(fp,pos) fseeko(fp, pos, SEEK_SET) +#endif + +void hexdump (const unsigned char *data, int size); +unsigned int read_byte_at (FILE *fp, off_t offset); +unsigned int read_2byte_at (FILE *fp, off_t offset); +unsigned int read_4byte_at (FILE *fp, off_t offset); +void read_bytes_at (FILE *fp, off_t offset, unsigned char *buffer, int size); + +#endif