aboutsummaryrefslogtreecommitdiff
path: root/src/SBaseFileTable.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avast.com>2022-02-06 18:05:34 +0100
committerLadislav Zezula <ladislav.zezula@avast.com>2022-02-06 18:05:34 +0100
commit9eef856125e84a00169f64a854241ff43f500592 (patch)
tree0e7ff5e34562a85ca2cd5e674ca892ccdb1034e2 /src/SBaseFileTable.cpp
parentca0e437ff5577870d6d757eba5b9430a781df4a2 (diff)
Fixed file search order for Starcraft I
Diffstat (limited to 'src/SBaseFileTable.cpp')
-rw-r--r--src/SBaseFileTable.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index 97fa3a2..90b7aa4 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -769,6 +769,7 @@ static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName,
{
TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
TMPQHash * pBestEntry = NULL;
+ TMPQHash * p1stEntry = NULL;
TMPQHash * pHash = pFirstHash;
// Parse the found hashes
@@ -776,26 +777,38 @@ static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName,
{
// Storm_2016.dll: 150209CB
// If the hash entry matches both locale and platform, return it immediately
- // Note: We only succeed this check if the locale is non-neutral, because
- // some Warcraft III maps have several items with neutral locale&platform, which leads
- // to wrong item being returned
+ // Only do that for non-0 locale&platform, because for loc&plat=0, there's different
+ // processing in Warcraft III vs. Starcraft, which is abused by some protectors.
if((lcLocale || Platform) && pHash->lcLocale == lcLocale && pHash->Platform == Platform)
return pHash;
// Storm_2016.dll: 150209D9
- // If (locale matches or is neutral) OR (platform matches or is neutral)
- // remember this as the best entry
+ // If (locale matches or is neutral) OR (platform matches or is neutral), remember this as the best entry
+ // Also remember the first matching entry for Starcraft maps
if(pHash->lcLocale == 0 || pHash->lcLocale == lcLocale)
{
if(pHash->Platform == 0 || pHash->Platform == Platform)
+ {
+ p1stEntry = (p1stEntry != NULL) ? p1stEntry : pHash;
pBestEntry = pHash;
+ }
}
// Get the next hash entry for that file
pHash = GetNextHashEntry(ha, pFirstHash, pHash);
}
- // At the end, return neutral hash (if found), otherwise NULL
+ //
+ // Different processing (Starcraft vs. Warcraft III), abused by some protectors
+ //
+ // * Starcraft I: for an entry with locale&platform = 0, then the first entry is returned
+ // Map: MPQ_2022_v1_Sniper.scx
+ // * Warcraft III: for an entry with locale&platform = 0, then the last entry is returned
+ // Map: MPQ_2015_v1_ProtectedMap_Spazy.w3x
+ //
+
+ if(ha->dwValidFileFlags == MPQ_FILE_VALID_FLAGS_SCX)
+ return p1stEntry;
return pBestEntry;
}