aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SFileOpenArchive.cpp50
-rw-r--r--test/StormTest.cpp17
2 files changed, 48 insertions, 19 deletions
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp
index 80ac9e1..dd178e5 100644
--- a/src/SFileOpenArchive.cpp
+++ b/src/SFileOpenArchive.cpp
@@ -31,6 +31,14 @@ static bool IsAviFile(DWORD * HeaderData)
return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C);
}
+static bool IsWarcraft3Map(DWORD * HeaderData)
+{
+ DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]);
+ DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderData[1]);
+
+ return (DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000);
+}
+
static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData)
{
TMPQUserData * pUserData;
@@ -153,6 +161,7 @@ bool WINAPI SFileOpenArchive(
TMPQArchive * ha = NULL; // Archive handle
TFileEntry * pFileEntry;
ULONGLONG FileSize = 0; // Size of the file
+ bool bIsWarcraft3Map = false;
int nError = ERROR_SUCCESS;
// Verify the parameters
@@ -237,28 +246,37 @@ bool WINAPI SFileOpenArchive(
}
// There are AVI files from Warcraft III with 'MPQ' extension.
- if(SearchOffset == 0 && IsAviFile(ha->HeaderData))
+ if(SearchOffset == 0)
{
- nError = ERROR_AVI_FILE;
- break;
+ if(IsAviFile(ha->HeaderData))
+ {
+ nError = ERROR_AVI_FILE;
+ break;
+ }
+
+ bIsWarcraft3Map = IsWarcraft3Map(ha->HeaderData);
}
- // If there is the MPQ user data signature, process it
+ // If there is the MPQ user data, process it
+ // Note that Warcraft III does not check for user data, which is abused by many map protectors
dwHeaderID = BSWAP_INT32_UNSIGNED(ha->HeaderData[0]);
- if(dwHeaderID == ID_MPQ_USERDATA && ha->pUserData == NULL && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
+ if(bIsWarcraft3Map == false && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
{
- // Verify if this looks like a valid user data
- pUserData = IsValidMpqUserData(SearchOffset, FileSize, ha->HeaderData);
- if(pUserData != NULL)
+ if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA)
{
- // Fill the user data header
- ha->UserDataPos = SearchOffset;
- ha->pUserData = &ha->UserData;
- memcpy(ha->pUserData, pUserData, sizeof(TMPQUserData));
-
- // Continue searching from that position
- SearchOffset += ha->pUserData->dwHeaderOffs;
- continue;
+ // Verify if this looks like a valid user data
+ pUserData = IsValidMpqUserData(SearchOffset, FileSize, ha->HeaderData);
+ if(pUserData != NULL)
+ {
+ // Fill the user data header
+ ha->UserDataPos = SearchOffset;
+ ha->pUserData = &ha->UserData;
+ memcpy(ha->pUserData, pUserData, sizeof(TMPQUserData));
+
+ // Continue searching from that position
+ SearchOffset += ha->pUserData->dwHeaderOffs;
+ continue;
+ }
}
}
diff --git a/test/StormTest.cpp b/test/StormTest.cpp
index 131b1d5..1601fda 100644
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -1751,6 +1751,7 @@ static int OpenExistingArchive(TLogHelper * pLogger, const char * szFullPath, DW
{
HANDLE hMpq = NULL;
TCHAR szMpqName[MAX_PATH];
+ bool bReopenResult;
int nError = ERROR_SUCCESS;
// Is it an encrypted MPQ ?
@@ -1768,8 +1769,14 @@ static int OpenExistingArchive(TLogHelper * pLogger, const char * szFullPath, DW
CopyFileName(szMpqName, szFullPath, strlen(szFullPath));
if(!SFileOpenArchive(szMpqName, 0, dwFlags, &hMpq))
{
+ // If the error is ERROR_BAD_FORMAT, try to open with MPQ_OPEN_FORCE_MPQ_V1
+// if((nError = GetLastError()) == ERROR_BAD_FORMAT)
+// {
+// bReopenResult = SFileOpenArchive(szMpqName, 0, dwFlags | MPQ_OPEN_FORCE_MPQ_V1, &hMpq);
+// nError = (bReopenResult == false) ? GetLastError() : ERROR_SUCCESS;
+// }
+
// Ignore the error if it's an AVI file or if the file is incomplete
- nError = GetLastError();
if(nError == ERROR_AVI_FILE || nError == ERROR_FILE_INCOMPLETE)
return nError;
@@ -2322,7 +2329,7 @@ static int TestOpenArchive(const char * szPlainName, const char * szListFile = N
bIsPartialMpq = (strstr(szPlainName, ".MPQ.part") != NULL);
// Copy the archive so we won't fuck up the original one
- nError = OpenExistingArchiveWithCopy(&Logger, szPlainName, NULL, &hMpq);
+ nError = OpenExistingArchiveWithCopy(&Logger, szPlainName, szPlainName, &hMpq);
if(nError == ERROR_SUCCESS)
{
// If the listfile was given, add it to the MPQ
@@ -4067,7 +4074,11 @@ int main(int argc, char * argv[])
// Open an Warcraft III map locked by the BOBA protector
if(nError == ERROR_SUCCESS)
nError = TestOpenArchive("MPQ_2002_v1_ProtectedMap_BOBA.w3m");
-
+*/
+ // Open an Warcraft III map locked by the BOBA protector
+ if(nError == ERROR_SUCCESS)
+ nError = TestOpenArchive("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x");
+/*
// Open an Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
if(nError == ERROR_SUCCESS)
nError = TestOpenArchive("MPQ_2014_v1_AttributesOneEntryLess.w3x");