From a2095bb8247067f6ff8dc42fe018ad4829497b2e Mon Sep 17 00:00:00 2001 From: Asheraf Date: Mon, 6 Nov 2023 21:00:15 +0100 Subject: [PATCH] Update grfio to work with big grf's on windows --- src/common/grfio.c | 21 ++++++++++----------- src/common/utils.c | 18 ++++++++++++++++++ src/common/utils.h | 2 ++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/common/grfio.c b/src/common/grfio.c index 12c609ce7f9..42cb65f0374 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -477,14 +477,14 @@ static void *grfio_reads(const char *fname, int *size) if (in != NULL) { int declen; unsigned char *buf = NULL; - fseek(in,0,SEEK_END); - declen = (int)ftell(in); + hseek(in,0,SEEK_END); + declen = (int)htell(in); if (declen == -1) { ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname); fclose(in); return NULL; } - fseek(in,0,SEEK_SET); + hseek(in,0,SEEK_SET); buf = aMalloc(declen+1); // +1 for resnametable zero-termination buf[declen] = '\0'; if (fread(buf, 1, declen, in) != (size_t)declen) { @@ -517,7 +517,7 @@ static void *grfio_reads(const char *fname, int *size) int fsize = entry->srclen_aligned; unsigned char *buf = aMalloc(fsize); unsigned char *buf2 = NULL; - if (fseek(in, entry->srcpos, SEEK_SET) != 0 + if (hseek(in, entry->srcpos, SEEK_SET) != 0 || fread(buf, 1, fsize, in) != (size_t)fsize) { ShowError("An error occurred in fread in grfio_reads, grfname=%s\n",grfname); aFree(buf); @@ -609,7 +609,6 @@ static bool grfio_is_full_encrypt(const char *fname) */ static int grfio_entryread(const char *grfname, int gentry) { - long grf_size; unsigned char grf_header[0x2e] = { 0 }; int entry,entrys,ofs,grf_version; unsigned char *grf_filelist; @@ -623,16 +622,16 @@ static int grfio_entryread(const char *grfname, int gentry) } ShowInfo("GRF data file found: '%s'\n", grfname); - fseek(fp,0,SEEK_END); - grf_size = ftell(fp); - fseek(fp,0,SEEK_SET); + hseek(fp,0,SEEK_END); + int64 grf_size = htell(fp); + hseek(fp,0,SEEK_SET); if (fread(grf_header,1,0x2e,fp) != 0x2e) { ShowError("Couldn't read all grf_header element of %s \n", grfname); fclose(fp); return 2; // 2:file format error } - if (strcmp((const char*)grf_header, "Master of Magic") != 0 || fseek(fp, getlong(grf_header+0x1e), SEEK_CUR) != 0) { + if (strcmp((const char*)grf_header, "Master of Magic") != 0 || hseek(fp, getlong(grf_header+0x1e), SEEK_CUR) != 0) { fclose(fp); ShowError("GRF %s read error\n", grfname); return 2; // 2:file format error @@ -642,7 +641,7 @@ static int grfio_entryread(const char *grfname, int gentry) if (grf_version == 0x01) { // ****** Grf version 01xx ****** - long list_size = grf_size - ftell(fp); + int64 list_size = grf_size - htell(fp); grf_filelist = aMalloc(list_size); if (fread(grf_filelist,1,list_size,fp) != (size_t)list_size) { ShowError("Couldn't read all grf_filelist element of %s \n", grfname); @@ -704,7 +703,7 @@ static int grfio_entryread(const char *grfname, int gentry) rSize = getlong(eheader); // Read Size eSize = getlong(eheader+4); // Extend Size - if ((long)rSize > grf_size-ftell(fp)) { + if ((long)rSize > grf_size-htell(fp)) { fclose(fp); ShowError("Illegal data format: GRF compress entry size\n"); return 4; diff --git a/src/common/utils.c b/src/common/utils.c index 18adcd0d368..a977481d89a 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -584,6 +584,24 @@ size_t hwrite(const void *ptr, size_t size, size_t count, FILE *stream) return fwrite(ptr, size, count, stream); } +int64 htell(FILE *stream) +{ +#ifdef WIN32 + return _ftelli64(stream); +#else + return ftell(stream); +#endif +} + +int hseek(FILE *stream, int64 offset, int origin) +{ +#ifdef WIN32 + return _fseeki64(stream, offset, origin); +#else + return fseek(stream, offset, origin); +#endif +} + void HCache_defaults(void) { HCache = &HCache_s; diff --git a/src/common/utils.h b/src/common/utils.h index df4ec589717..c4df246d741 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -81,6 +81,8 @@ extern float GetFloat(const unsigned char* buf); size_t hread(void * ptr, size_t size, size_t count, FILE * stream); size_t hwrite(const void * ptr, size_t size, size_t count, FILE * stream); +int64 htell(FILE *stream); +int hseek(FILE *stream, int64 offset, int origin); #endif // HERCULES_CORE #ifdef WIN32