diff options
-rw-r--r-- | src/SFileOpenArchive.cpp | 50 | ||||
-rw-r--r-- | test/StormTest.cpp | 17 |
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"); |