mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
On Windows, check for case-mismatched file names on successful kopen4load().
When a file from the local file system is opened, its real file name is gotten with SHGetFileInfo() and compared against the one that was passed. In the case they're not identical, a warning is issued. This is one step towards eliminating mismatched file names in DEFs etc., which cause trouble on systems that look them up case-sensitively. However, it's not perfect because the issue is trickier than it appears on first sight. For one thing, this will only check the last (i.e. file) part in the path, falsely accepting mismatched directory names. However for these, it reports them ruthlessly, even for those names where the try-other-case hack (try all uppercase, all lowercase) would find the correctly-cased file. git-svn-id: https://svn.eduke32.com/eduke32@2692 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
f69d9f241d
commit
68c701fb4a
1 changed files with 79 additions and 1 deletions
|
@ -6,6 +6,10 @@
|
||||||
// by Jonathon Fowler (jf@jonof.id.au)
|
// by Jonathon Fowler (jf@jonof.id.au)
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
#ifdef _WIN32
|
||||||
|
// for FILENAME_CASE_CHECK
|
||||||
|
# include <shellapi.h>
|
||||||
|
#endif
|
||||||
#include "cache1d.h"
|
#include "cache1d.h"
|
||||||
#include "pragmas.h"
|
#include "pragmas.h"
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
|
@ -443,6 +447,16 @@ int32_t findfrompath(const char *fn, char **where)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define FILENAME_CASE_CHECK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FILENAME_CASE_CHECK
|
||||||
|
// don't free pfn if !=0 AND we Bopen()'ed the file successfully
|
||||||
|
static int32_t dont_free_pfn;
|
||||||
|
static char *lastpfn;
|
||||||
|
#endif
|
||||||
|
|
||||||
int32_t openfrompath(const char *fn, int32_t flags, int32_t mode)
|
int32_t openfrompath(const char *fn, int32_t flags, int32_t mode)
|
||||||
{
|
{
|
||||||
char *pfn;
|
char *pfn;
|
||||||
|
@ -450,7 +464,12 @@ int32_t openfrompath(const char *fn, int32_t flags, int32_t mode)
|
||||||
|
|
||||||
if (findfrompath(fn, &pfn) < 0) return -1;
|
if (findfrompath(fn, &pfn) < 0) return -1;
|
||||||
h = Bopen(pfn, flags, mode);
|
h = Bopen(pfn, flags, mode);
|
||||||
Bfree(pfn);
|
#ifdef FILENAME_CASE_CHECK
|
||||||
|
if (h>=0 && dont_free_pfn)
|
||||||
|
lastpfn = pfn;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
Bfree(pfn);
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -666,6 +685,24 @@ void uninitgroupfile(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FILENAME_CASE_CHECK
|
||||||
|
// See
|
||||||
|
// http://stackoverflow.com/questions/74451/getting-actual-file-name-with-proper-casing-on-windows
|
||||||
|
// for relevant discussion.
|
||||||
|
|
||||||
|
static SHFILEINFO shinf;
|
||||||
|
|
||||||
|
// -1: failure, 0: match, 1: mismatch
|
||||||
|
static int32_t check_filename_mismatch(const char *filename, int32_t 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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int32_t kopen4load(const char *filename, char searchfirst)
|
int32_t kopen4load(const char *filename, char searchfirst)
|
||||||
{
|
{
|
||||||
int32_t j, k, fil, newhandle = MAXOPENFILES-1;
|
int32_t j, k, fil, newhandle = MAXOPENFILES-1;
|
||||||
|
@ -685,14 +722,55 @@ int32_t kopen4load(const char *filename, char searchfirst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FILENAME_CASE_CHECK
|
||||||
|
dont_free_pfn = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (searchfirst == 0 && (fil = openfrompath(filename,BO_BINARY|BO_RDONLY,S_IREAD)) >= 0)
|
if (searchfirst == 0 && (fil = openfrompath(filename,BO_BINARY|BO_RDONLY,S_IREAD)) >= 0)
|
||||||
{
|
{
|
||||||
|
#ifdef FILENAME_CASE_CHECK
|
||||||
|
int32_t status;
|
||||||
|
char *cp, *lastslash;
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bfree(lastpfn);
|
||||||
|
lastpfn=NULL;
|
||||||
|
#endif
|
||||||
filegrp[newhandle] = 255;
|
filegrp[newhandle] = 255;
|
||||||
filehan[newhandle] = fil;
|
filehan[newhandle] = fil;
|
||||||
filepos[newhandle] = 0;
|
filepos[newhandle] = 0;
|
||||||
return(newhandle);
|
return(newhandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FILENAME_CASE_CHECK
|
||||||
|
dont_free_pfn = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (; toupperlookup[*filename] == '/'; filename++);
|
for (; toupperlookup[*filename] == '/'; filename++);
|
||||||
|
|
||||||
#ifdef WITHKPLIB
|
#ifdef WITHKPLIB
|
||||||
|
|
Loading…
Reference in a new issue