.fixed potential memory issue when loading CD game after a large ROM file

.added support for upper-case ROM file extensions
.modified load_archive behavior so that it does not overwrite original filename with uncompressed name anymore
.replaced use of strcmp by memcmp
This commit is contained in:
EkeEke 2012-07-15 17:39:47 +02:00
parent 2b8656c27f
commit 47040dbba6
10 changed files with 75 additions and 94 deletions

View File

@ -348,7 +348,7 @@ void gen_tmss_w(unsigned int offset, unsigned int data)
WRITE_WORD(tmss, offset, data);
/* VDP requires "SEGA" value to be written in TMSS register */
if (strncmp((char *)tmss, "SEGA", 4) == 0)
if (memcmp((char *)tmss, "SEGA", 4) == 0)
{
for (i=0xc0; i<0xe0; i+=8)
{

View File

@ -61,7 +61,7 @@ static int config_load(void)
char version[16];
fseek(fp, 0, SEEK_SET);
fread(version, 16, 1, fp);
if (strncmp(version,CONFIG_VERSION,16))
if (memcmp(version,CONFIG_VERSION,16))
{
fclose(fp);
return 0;

View File

@ -83,37 +83,7 @@ static inline u16 FLIP16 (u16 b)
return c;
}
void get_zipfilename(char *filename)
{
char in[CHUNKSIZE];
/* Open file */
FILE *fd = fopen(filename, "rb");
if (!fd) return;
/* Read first 2 bytes */
fread(in, 2, 1, fd);
/* Detect Zip file */
if (memcmp(in, "PK", 2) == 0)
{
/* Read remaining header data */
fread(in + 2, sizeof(PKZIPHEADER) - 2, 1, fd);
/* Zip header pointer */
PKZIPHEADER *pkzip = (PKZIPHEADER *) in;
/* Return compressed file name */
int len = FLIP16(pkzip->filenameLength);
if (len >= MAXPATHLEN) len = MAXPATHLEN - 1;
fread(filename, len, 1, fd);
filename[len] = 0;
}
fclose(fd);
}
int load_archive(char *filename, unsigned char *buffer, int maxsize)
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
{
int size = 0;
char in[CHUNKSIZE];
@ -132,7 +102,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
/* Mega CD BIOS are required files */
if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP))
{
sprintf(msg,"Unable to open CD BIOS");
sprintf(msg,"Unable to open %s", filename + 14);
}
if (!fd)
@ -187,19 +157,23 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
return 0;
}
/* Compressed filename offset */
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength);
if (extension)
{
memcpy(extension, &in[offset - 3], 3);
extension[3] = 0;
}
/* Initial Zip buffer offset */
int offset = sizeof (PKZIPHEADER) + FLIP16(pkzip->filenameLength) + FLIP16(pkzip->extraDataLength);
offset += FLIP16(pkzip->extraDataLength);
zs.next_in = (Bytef *)&in[offset];
/* Initial Zip remaining chunk size */
zs.avail_in = CHUNKSIZE - offset;
/* Overwrite input filename with compressed filename */
offset = FLIP16(pkzip->filenameLength);
if (offset >= MAXPATHLEN) offset = MAXPATHLEN - 1;
strncpy(filename, &in[sizeof(PKZIPHEADER)], offset);
filename[offset] = 0;
/* Start unzipping file */
do
{
@ -255,6 +229,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
sprintf((char *)msg,"Loading %d bytes ...", size);
GUI_MsgBoxOpen("Information", (char *)msg, 1);
/* filename extension */
if (extension)
{
memcpy(extension, &filename[strlen(filename) - 3], 3);
extension[3] = 0;
}
/* Read into buffer */
int left = size;
while (left > CHUNKSIZE)

View File

@ -42,6 +42,6 @@
#define _FILEIO_H_
/* Function prototypes */
int load_archive(char *filename, unsigned char *buffer, int maxsize);
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
#endif /* _FILEIO_H_ */

View File

@ -118,7 +118,7 @@ static void init_machine(void)
fclose(fp);
/* check BOOT ROM */
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
{
/* mark Genesis BIOS as loaded */
system_bios = SYSTEM_MD;

View File

@ -403,13 +403,13 @@ int load_bios(void)
switch (region_code)
{
case REGION_USA:
size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom));
size = load_archive(CD_BIOS_US, scd.bootrom, sizeof(scd.bootrom), 0);
break;
case REGION_EUROPE:
size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom));
size = load_archive(CD_BIOS_EU, scd.bootrom, sizeof(scd.bootrom), 0);
break;
default:
size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom));
size = load_archive(CD_BIOS_JP, scd.bootrom, sizeof(scd.bootrom), 0);
break;
}
@ -458,7 +458,7 @@ int load_bios(void)
if (cart.romsize <= 0x400000)
{
/* load Game Gear "BIOS" file */
size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000);
size = load_archive(GG_BIOS, cart.rom + 0x400000, 0x100000, 0);
if (size > 0)
{
@ -489,13 +489,13 @@ int load_bios(void)
switch (region_code)
{
case REGION_USA:
size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x100000);
size = load_archive(MS_BIOS_US, cart.rom + 0x400000, 0x100000, 0);
break;
case REGION_EUROPE:
size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x100000);
size = load_archive(MS_BIOS_EU, cart.rom + 0x400000, 0x100000, 0);
break;
default:
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000);
size = load_archive(MS_BIOS_JP, cart.rom + 0x400000, 0x100000, 0);
break;
}
@ -548,9 +548,13 @@ int load_rom(char *filename)
{
cdd_unload();
}
else
{
cdd.loaded = 0;
}
/* .cue file support */
if (!strncmp(".cue", &filename[strlen(filename) - 4], 4))
if (!memcmp(".cue", &filename[strlen(filename) - 4], 4))
{
/* open associated .bin file */
strncpy(&filename[strlen(filename) - 4], ".bin", 4);
@ -565,7 +569,7 @@ int load_rom(char *filename)
}
/* auto-detect CD image file */
if (!strncmp("SEGADISCSYSTEM", buf + 0x10, 14))
if (!memcmp("SEGADISCSYSTEM", buf + 0x10, 14))
{
/* file header pointer (BIN format) */
header = buf + 0x10;
@ -573,7 +577,7 @@ int load_rom(char *filename)
/* enable CD hardware */
system_hw = SYSTEM_MCD;
}
else if (!strncmp("SEGADISCSYSTEM", buf, 14))
else if (!memcmp("SEGADISCSYSTEM", buf, 14))
{
/* file header pointer (ISO format) */
header = buf;
@ -583,25 +587,29 @@ int load_rom(char *filename)
}
else
{
/* load file into ROM buffer (input filename is overwritten by uncompressed filename) */
int size = load_archive(filename, cart.rom, sizeof(cart.rom));
/* load file into ROM buffer */
char extension[4];
int size = load_archive(filename, cart.rom, sizeof(cart.rom), extension);
if (!size) return(0);
/* mark CD BIOS as unloaded */
system_bios &= ~0x10;
/* convert lower case to upper case */
*(uint32 *)(extension) &= 0xdfdfdfdf;
/* Auto-detect system hardware from ROM file extension */
if (!strncmp(".sms", &filename[strlen(filename) - 4], 4))
if (!memcmp("SMS", &extension[0], 3))
{
/* Master System II hardware */
system_hw = SYSTEM_SMS2;
}
else if (!strncmp(".gg", &filename[strlen(filename) - 3], 3))
else if (!memcmp("GG", &extension[1], 2))
{
/* Game Gear hardware (GG mode) */
system_hw = SYSTEM_GG;
}
else if (!strncmp(".sg", &filename[strlen(filename) - 3], 3))
else if (!memcmp("SG", &extension[1], 2))
{
/* SG-1000 hardware */
system_hw = SYSTEM_SG;
@ -612,7 +620,7 @@ int load_rom(char *filename)
system_hw = SYSTEM_MD;
/* Decode .MDX format */
if (!strncmp(".mdx", &filename[strlen(filename) - 4], 4))
if (!memcmp("MDX", &extension[0], 3))
{
for (i = 4; i < size - 1; i++)
{
@ -623,7 +631,7 @@ int load_rom(char *filename)
}
/* auto-detect 512 byte extra header */
if (strncmp((char *)(cart.rom + 0x100),"SEGA", 4) && ((size / 512) & 1))
if (memcmp((char *)(cart.rom + 0x100), "SEGA", 4) && ((size / 512) & 1))
{
/* remove header */
size -= 512;
@ -817,12 +825,12 @@ void get_region(char *romheader)
int country = 0;
/* from Gens */
if (!strncmp(rominfo.country, "eur", 3)) country |= 8;
else if (!strncmp(rominfo.country, "EUR", 3)) country |= 8;
else if (!strncmp(rominfo.country, "jap", 3)) country |= 1;
else if (!strncmp(rominfo.country, "JAP", 3)) country |= 1;
else if (!strncmp(rominfo.country, "usa", 3)) country |= 4;
else if (!strncmp(rominfo.country, "USA", 3)) country |= 4;
if (!memcmp(rominfo.country, "eur", 3)) country |= 8;
else if (!memcmp(rominfo.country, "EUR", 3)) country |= 8;
else if (!memcmp(rominfo.country, "jap", 3)) country |= 1;
else if (!memcmp(rominfo.country, "JAP", 3)) country |= 1;
else if (!memcmp(rominfo.country, "usa", 3)) country |= 4;
else if (!memcmp(rominfo.country, "USA", 3)) country |= 4;
else
{
int i;

View File

@ -46,7 +46,7 @@ int state_load(unsigned char *state)
char version[17];
load_param(version,16);
version[16] = 0;
if (strncmp(version,STATE_VERSION,11))
if (memcmp(version,STATE_VERSION,11))
{
return -1;
}

View File

@ -45,9 +45,8 @@
#include <zlib.h>
static int check_zip(char *filename);
static int gzsize(gzFile *gd);
int load_archive(char *filename, unsigned char *buffer, int maxsize)
int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension)
{
int size = 0;
@ -55,6 +54,7 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
{
unz_file_info info;
int ret = 0;
char fname[256];
/* Attempt to open the archive */
unzFile *fd = unzOpen(filename);
@ -69,13 +69,20 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
}
/* Get file informations and update filename */
ret = unzGetCurrentFileInfo(fd, &info, filename, 128, NULL, 0, NULL, 0);
ret = unzGetCurrentFileInfo(fd, &info, fname, 256, NULL, 0, NULL, 0);
if(ret != UNZ_OK)
{
unzClose(fd);
return 0;
}
/* Compressed filename extension */
if (extension)
{
strncpy(extension, &fname[strlen(fname) - 3], 3);
extension[3] = 0;
}
/* Open the file for reading */
ret = unzOpenCurrentFile(fd);
if(ret != UNZ_OK)
@ -121,6 +128,13 @@ int load_archive(char *filename, unsigned char *buffer, int maxsize)
/* Read file data */
size = gzread(gd, buffer, maxsize);
/* filename extension */
if (extension)
{
strncpy(extension, &filename[strlen(filename) - 3], 3);
extension[3] = 0;
}
/* Close file */
gzclose(gd);
}
@ -143,25 +157,3 @@ static int check_zip(char *filename)
if(memcmp(buf, "PK", 2) == 0) return (1);
return (0);
}
/*
Returns the size of a GZ compressed file.
*/
static int gzsize(gzFile *gd)
{
#define CHUNKSIZE (0x10000)
int size = 0, length = 0;
unsigned char buffer[CHUNKSIZE];
gzrewind(gd);
do
{
size = gzread(gd, buffer, CHUNKSIZE);
if(size <= 0) break;
length += size;
}
while (!gzeof(gd));
gzrewind(gd);
return (length);
#undef CHUNKSIZE
}

View File

@ -43,6 +43,6 @@
#define _FILEIO_H_
/* Function prototypes */
extern int load_archive(char *filename, unsigned char *buffer, int maxsize);
extern int load_archive(char *filename, unsigned char *buffer, int maxsize, char *extension);
#endif /* _FILEIO_H_ */

View File

@ -701,7 +701,7 @@ int main (int argc, char **argv)
fclose(fp);
/* check BOOT ROM */
if (!strncmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
{
/* mark Genesis BIOS as loaded */
system_bios = SYSTEM_MD;