aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2016-09-30 11:23:29 +0200
committerLadislav Zezula <ladislav.zezula@avg.com>2016-09-30 11:23:29 +0200
commitb8fb98fcc4aa2d1c6ab6ce57b6b2e10a25861a56 (patch)
treecf732fe901659a7bb7e80c3aafd30bb813c0b28e /src
parent8a370dd9336540b8be585272182de0f74aac9241 (diff)
+ Yet another protector
Diffstat (limited to 'src')
-rw-r--r--src/SBaseCommon.cpp2
-rw-r--r--src/SBaseDumpData.cpp4
-rw-r--r--src/SBaseFileTable.cpp40
-rw-r--r--src/SBaseSubTypes.cpp4
-rw-r--r--src/StormLib.h7
5 files changed, 35 insertions, 22 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
index 977664a..aa891df 100644
--- a/src/SBaseCommon.cpp
+++ b/src/SBaseCommon.cpp
@@ -721,7 +721,7 @@ TMPQHash * AllocateHashEntry(
pHash->dwName1 = dwName1;
pHash->dwName2 = dwName2;
pHash->lcLocale = (USHORT)lcLocale;
- pHash->wPlatform = 0;
+ pHash->Platform = 0;
pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
}
diff --git a/src/SBaseDumpData.cpp b/src/SBaseDumpData.cpp
index d156030..334561b 100644
--- a/src/SBaseDumpData.cpp
+++ b/src/SBaseDumpData.cpp
@@ -51,11 +51,11 @@ void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize)
printf("== Hash Table =================================\n");
for(i = 0; i < dwHashTableSize; i++)
{
- printf("[%08x] %08X %08X %04X %04X %08X\n", i,
+ printf("[%08x] %08X %08X %04X %02X %08X\n", i,
pHashTable[i].dwName1,
pHashTable[i].dwName2,
pHashTable[i].lcLocale,
- pHashTable[i].wPlatform,
+ pHashTable[i].Platform,
pHashTable[i].dwBlockIndex);
}
printf("-----------------------------------------------\n\n");
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index fe5eb78..c7a26aa 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -612,32 +612,42 @@ static bool IsValidHashEntry1(TMPQArchive * ha, TMPQHash * pHash, TMPQBlock * pB
}
// Returns a hash table entry in the following order:
-// 1) A hash table entry with the preferred locale
-// 2) A hash table entry with the neutral locale
+// 1) A hash table entry with the preferred locale and platform
+// 2) A hash table entry with the neutral|matching locale and neutral|matching platform
// 3) NULL
-static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+// Storm_2016.dll: 15020940
+static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale, BYTE Platform)
{
- TMPQHash * pHashNeutral = NULL;
TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
+ TMPQHash * pBestEntry = NULL;
TMPQHash * pHash = pFirstHash;
// Parse the found hashes
while(pHash != NULL)
{
- // If the locales match, return it
- if(lcLocale == pHash->lcLocale)
+ // 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
+ if((lcLocale || Platform) && pHash->lcLocale == lcLocale && pHash->Platform == Platform)
return pHash;
-
- // If we found neutral hash, remember it
- if(pHash->lcLocale == 0)
- pHashNeutral = pHash;
+
+ // Storm_2016.dll: 150209D9
+ // If (locale matches or is neutral) OR (platform matches or is neutral)
+ // remember this as the best entry
+ if(pHash->lcLocale == 0 || pHash->lcLocale == lcLocale)
+ {
+ if(pHash->Platform == 0 || pHash->Platform == Platform)
+ 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
- return pHashNeutral;
+ return pBestEntry;
}
// Returns a hash table entry in the following order:
@@ -1803,7 +1813,7 @@ TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID
// we will need the pointer to hash table entry
if(ha->pHashTable != NULL)
{
- pHash = GetHashEntryLocale(ha, szFileName, lcLocale);
+ pHash = GetHashEntryLocale(ha, szFileName, lcLocale, 0);
if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
{
if(PtrHashIndex != NULL)
@@ -1987,7 +1997,8 @@ int RenameFileEntry(
pHashEntry->dwName1 = 0xFFFFFFFF;
pHashEntry->dwName2 = 0xFFFFFFFF;
pHashEntry->lcLocale = 0xFFFF;
- pHashEntry->wPlatform = 0xFFFF;
+ pHashEntry->Platform = 0xFF;
+ pHashEntry->Reserved = 0xFF;
pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED;
}
@@ -2027,7 +2038,8 @@ int DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf)
pHashEntry->dwName1 = 0xFFFFFFFF;
pHashEntry->dwName2 = 0xFFFFFFFF;
pHashEntry->lcLocale = 0xFFFF;
- pHashEntry->wPlatform = 0xFFFF;
+ pHashEntry->Platform = 0xFF;
+ pHashEntry->Reserved = 0xFF;
pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED;
}
diff --git a/src/SBaseSubTypes.cpp b/src/SBaseSubTypes.cpp
index 333b881..47c205e 100644
--- a/src/SBaseSubTypes.cpp
+++ b/src/SBaseSubTypes.cpp
@@ -216,7 +216,7 @@ TMPQHash * LoadSqpHashTable(TMPQArchive * ha)
// Store the rest. Note that this must be done last,
// because block index corresponds to pMpqHash->dwName2
pMpqHash->dwBlockIndex = MPQ_BLOCK_INDEX(pSqpHash);
- pMpqHash->wPlatform = 0;
+ pMpqHash->Platform = 0;
pMpqHash->lcLocale = 0;
}
}
@@ -544,7 +544,7 @@ TMPQHash * LoadMpkHashTable(TMPQArchive * ha)
// Copy the MPK hash entry to the hash table
pHash->dwBlockIndex = pMpkHash[i].dwBlockIndex;
- pHash->wPlatform = 0;
+ pHash->Platform = 0;
pHash->lcLocale = 0;
pHash->dwName1 = pMpkHash[i].dwName2;
pHash->dwName2 = pMpkHash[i].dwName3;
diff --git a/src/StormLib.h b/src/StormLib.h
index 3621096..b6df481 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -617,12 +617,13 @@ typedef struct _TMPQHash
// The platform the file is used for. 0 indicates the default platform.
// No other values have been observed.
- // Note: wPlatform is actually just BYTE, but since it has never been used, we don't care.
- USHORT wPlatform;
+ BYTE Platform;
+ BYTE Reserved;
#else
- USHORT wPlatform;
+ BYTE Platform;
+ BYTE Reserved;
USHORT lcLocale;
#endif