Only check file name case when not in-game; don't warn for ALLUPPER or alllower.

The first means that the expensive (~0.5 ms) SHGetFileInfo() calls won't inter-
fere with smooth gameplay, but files that are opened only at game-time like
sounds won't be checked.  The second means that there are now less false
positives, i.e. warnings about files that would be found due to the
check-all-{upper,lower} hack.

git-svn-id: https://svn.eduke32.com/eduke32@2702 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-05-28 18:15:19 +00:00
parent 689e1b7167
commit 0088ed0591
3 changed files with 89 additions and 28 deletions

View file

@ -467,6 +467,7 @@ int32_t openfrompath(const char *fn, int32_t flags, int32_t mode)
int32_t h;
if (findfrompath(fn, &pfn) < 0) return -1;
h = Bopen(pfn, flags, mode);
#ifdef FILENAME_CASE_CHECK
if (h>=0 && dont_free_pfn)
@ -696,14 +697,41 @@ void uninitgroupfile(void)
static SHFILEINFO shinf;
int32_t (*check_filename_casing_fn)(void) = NULL;
// -1: failure, 0: match, 1: mismatch
static int32_t check_filename_mismatch(const char *filename, int32_t ofs)
{
const char *fn = filename+ofs;
// we assume that UNICODE is not #defined, winlayer.c errors out else
if (!SHGetFileInfo(filename, -1, &shinf, sizeof(shinf), SHGFI_DISPLAYNAME))
return -1;
return !!Bstrcmp(shinf.szDisplayName, filename+ofs);
if (!Bstrcmp(shinf.szDisplayName, fn))
return 0;
{
char *tfn = Bstrtolower(Bstrdup(fn));
if (!Bstrcmp(shinf.szDisplayName, tfn))
{
Bfree(tfn);
return 0;
}
Bstrupr(tfn);
if (!Bstrcmp(shinf.szDisplayName, tfn))
{
Bfree(tfn);
return 0;
}
Bfree(tfn);
}
return 1;
}
#endif
@ -713,6 +741,10 @@ int32_t kopen4load(const char *filename, char searchfirst)
char bad, *gfileptr;
intptr_t i;
#ifdef FILENAME_CASE_CHECK
const int32_t do_case_check = check_filename_casing_fn && check_filename_casing_fn();
#endif
if (filename==NULL)
return -1;
@ -727,43 +759,46 @@ int32_t kopen4load(const char *filename, char searchfirst)
}
#ifdef FILENAME_CASE_CHECK
dont_free_pfn = 1;
dont_free_pfn = do_case_check;
#endif
if (searchfirst == 0 && (fil = openfrompath(filename,BO_BINARY|BO_RDONLY,S_IREAD)) >= 0)
{
#ifdef FILENAME_CASE_CHECK
int32_t status;
char *cp, *lastslash;
if (check_filename_casing_fn && check_filename_casing_fn())
{
int32_t status;
char *cp, *lastslash;
// convert all slashes to backslashes because SHGetFileInfo()
// complains else!
lastslash = lastpfn;
for (cp=lastpfn; *cp; cp++)
if (*cp=='/')
// convert all slashes to backslashes because SHGetFileInfo()
// complains else!
lastslash = lastpfn;
for (cp=lastpfn; *cp; cp++)
if (*cp=='/')
{
*cp = '\\';
lastslash = cp;
}
if (lastslash != lastpfn)
lastslash++;
status = check_filename_mismatch(lastpfn, lastslash-lastpfn);
dont_free_pfn = 0;
if (status == -1)
{
*cp = '\\';
lastslash = cp;
initprintf("SHGetFileInfo failed with error code %lu\n", GetLastError());
}
else if (status == 1)
{
initprintf("warning: case mismatch: passed \"%s\", real \"%s\"\n",
lastslash, shinf.szDisplayName);
}
if (lastslash != lastpfn)
lastslash++;
status = check_filename_mismatch(lastpfn, lastslash-lastpfn);
dont_free_pfn = 0;
if (status == -1)
{
initprintf("SHGetFileInfo failed with error code %lu\n", GetLastError());
Bfree(lastpfn);
lastpfn=NULL;
}
else if (status == 1)
{
initprintf("warning: case mismatch: passed \"%s\", real \"%s\"\n",
lastslash, shinf.szDisplayName);
}
Bfree(lastpfn);
lastpfn=NULL;
#endif
filegrp[newhandle] = 255;
filehan[newhandle] = fil;

View file

@ -8687,11 +8687,24 @@ static void G_CheckCommandLine(int32_t argc, const char **argv)
}
#undef COPYARG
#ifdef _WIN32
// See FILENAME_CASE_CHECK in cache1d.c
static int32_t check_filename_casing(void)
{
return 1;
}
#endif
int32_t ExtPreInit(int32_t argc,const char **argv)
{
wm_setapptitle("Mapster32");
#ifdef _WIN32
{
extern int32_t (*check_filename_casing_fn)(void);
check_filename_casing_fn = check_filename_casing;
}
tempbuf[GetModuleFileName(NULL,tempbuf,BMAX_PATH)] = 0;
Bcorrectfilename(tempbuf,1);
//chdir(tempbuf);

View file

@ -9834,6 +9834,14 @@ void app_crashhandler(void)
}
#endif
#ifdef _WIN32
// See FILENAME_CASE_CHECK in cache1d.c
static int32_t check_filename_casing(void)
{
return !(g_player[myconnectindex].ps->gm&MODE_GAME);
}
#endif
#ifdef GEKKO
void L2Enhance();
void CON_EnableGecko(int channel,int safe);
@ -9885,6 +9893,11 @@ int32_t app_main(int32_t argc, const char **argv)
#endif
#ifdef _WIN32
{
extern int32_t (*check_filename_casing_fn)(void);
check_filename_casing_fn = check_filename_casing;
}
tempbuf[GetModuleFileName(NULL,g_rootDir,BMAX_PATH)] = 0;
Bcorrectfilename(g_rootDir,1);
//chdir(g_rootDir);