From 5ced3835f9d52584bc20fb6a3a0e58069374e9af Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Fri, 17 Dec 2021 22:27:34 +0100 Subject: Tests updated --- test/StormTest.cpp | 359 ++++++++++++++++++++++++++-------------------------- test/TLogHelper.cpp | 79 +++++++----- 2 files changed, 230 insertions(+), 208 deletions(-) (limited to 'test') diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 3ba9b1e..13b0ace 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -35,16 +35,18 @@ //------------------------------------------------------------------------------ // Local structures -#define TEST_FLAG_PROTECTED 0x01000000 -#define TEST_FLAG_FILE_COUNT 0x00FFFFFF +#define TFLG_COUNT_HASH 0x01000000 // There is file count in the lower 24-bits, then hash +#define TFLG_WILL_FAIL 0x02000000 // The process is expected to fail +#define TFLG_COUNT_MASK 0x00FFFFFF // Mask for file count +#define TEST_DATA(hash, num) (num | TFLG_COUNT_HASH), hash typedef struct _TEST_INFO { LPCTSTR szMpqName1; LPCTSTR szMpqName2; DWORD dwFlags; - LPCSTR szFileName1; - LPCSTR szFileName2; + const void * param1; + const void * param2; } TEST_INFO, *PTEST_INFO; typedef struct _LINE_INFO @@ -80,6 +82,8 @@ static const TCHAR szListFileDir[] = { '1', '9', '9', '5', ' ', '-', ' ', 'T', ' // Global for the work MPQ static LPCTSTR szMpqSubDir = _T("1995 - Test MPQs"); static LPCTSTR szMpqPatchDir = _T("1995 - Test MPQs\\patches"); +static LPCSTR IntToHexChar = "0123456789abcdef"; + typedef DWORD (*FIND_FILE_CALLBACK)(LPCTSTR szFullPath); @@ -353,23 +357,27 @@ static bool IsMpqExtension(LPCTSTR szFileName) return false; } -static void BinaryFromString(LPCSTR szBinary, LPBYTE pbBuffer, DWORD cbBuffer) +// Converts binary array to string. +// The caller must ensure that the buffer has at least ((cbBinary * 2) + 1) characters +template +xchar * StringFromBinary(LPBYTE pbBinary, size_t cbBinary, xchar * szBuffer) { - LPBYTE pbBufferEnd = pbBuffer + cbBuffer; - char * szTemp; - char szHexaDigit[4]; + xchar * szSaveBuffer = szBuffer; - while(szBinary[0] != 0 && pbBuffer < pbBufferEnd) + // Verify the binary pointer + if(pbBinary && cbBinary) { - // Get the 2-byte chunk - szHexaDigit[0] = szBinary[0]; - szHexaDigit[1] = szBinary[1]; - szHexaDigit[2] = 0; - - // Convert to integer - *pbBuffer++ = (BYTE)strtoul(szHexaDigit, &szTemp, 16); - szBinary += 2; + // Convert the bytes to string array + for(size_t i = 0; i < cbBinary; i++) + { + *szBuffer++ = IntToHexChar[pbBinary[i] >> 0x04]; + *szBuffer++ = IntToHexChar[pbBinary[i] & 0x0F]; + } } + + // Terminate the string + *szBuffer = 0; + return szSaveBuffer; } static void AddStringBeforeExtension(char * szBuffer, LPCSTR szFileName, LPCSTR szExtraString) @@ -922,23 +930,23 @@ static DWORD GetFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileN return nPatchCount; } -static DWORD VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, int nExpectedPatchCount) +static DWORD VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, DWORD dwExpectedPatchCount) { - int nPatchCount = 0; + DWORD dwPatchCount = 0; // Retrieve the patch count pLogger->PrintProgress(_T("Verifying patch count for %s ..."), szFileName); - nPatchCount = GetFilePatchCount(pLogger, hMpq, szFileName); + dwPatchCount = GetFilePatchCount(pLogger, hMpq, szFileName); // Check if there are any patches at all - if(nExpectedPatchCount != 0 && nPatchCount == 0) + if(dwExpectedPatchCount != 0 && dwPatchCount == 0) { pLogger->PrintMessage("There are no patches for %s", szFileName); return ERROR_FILE_CORRUPT; } // Check if the number of patches fits - if(nPatchCount != nExpectedPatchCount) + if(dwPatchCount != dwExpectedPatchCount) { pLogger->PrintMessage("Unexpected number of patches for %s", szFileName); return ERROR_FILE_CORRUPT; @@ -2452,12 +2460,12 @@ static DWORD TestArchive( LPCTSTR szPlainName, // Plain name of the MPQ LPCTSTR szListFile, // Listfile name (NULL if none) DWORD dwFlags, // Flags - LPCSTR szFileName1, - LPCSTR szFileName2) + LPCSTR szParam1, + LPCSTR szParam2) { - TFileData * pFileData1 = NULL; - TFileData * pFileData2 = NULL; + TFileData * FileDataList[2] = {NULL}; TLogHelper Logger("TestMpq", szPlainName); + LPCSTR FileNameList[2] = {NULL}; LPCSTR szExpectedMD5 = NULL; HANDLE hMpq = NULL; DWORD dwFileCount = 0; @@ -2467,8 +2475,7 @@ static DWORD TestArchive( DWORD dwExpectedFileCount = 0; DWORD dwMpqFlags = 0; TCHAR szFullName[MAX_PATH]; - BYTE ExpectedMD5[MD5_DIGEST_SIZE]; - BYTE OverallMD5[MD5_DIGEST_SIZE]; + BYTE ObtainedMD5[MD5_DIGEST_SIZE] = {0}; bool bIgnoreOpedwErrCodes = false; // If the file is a partial MPQ, don't load all files @@ -2476,14 +2483,18 @@ static DWORD TestArchive( dwSearchFlags |= SEARCH_FLAG_LOAD_FILES; // If the MPQ is a protected MPQ, do different tests - if(dwFlags & TEST_FLAG_PROTECTED) + if(dwFlags & TFLG_COUNT_HASH) { - dwExpectedFileCount = (dwFlags & TEST_FLAG_FILE_COUNT); - if((szExpectedMD5 = szFileName1) != NULL) + if((szExpectedMD5 = szParam1) != NULL) dwSearchFlags |= SEARCH_FLAG_HASH_FILES; - szFileName2 = szFileName1 = NULL; + dwExpectedFileCount = (dwFlags & TFLG_COUNT_MASK); + szParam1 = NULL; } + // Put all file names into list + FileNameList[0] = szParam1; + FileNameList[1] = szParam2; + // Copy the archive so we won't fuck up the original one dwErrCode = OpenExistingArchiveWithCopy(&Logger, szPlainName, NULL, &hMpq); while(dwErrCode == ERROR_SUCCESS) @@ -2510,49 +2521,43 @@ static DWORD TestArchive( if(dwErrCode != ERROR_SUCCESS) break; - // If szFileName1 was given, load it and check its CRC - if(szFileName1 && szFileName1[0]) + // For every file name given, load it and check its CRC + for(size_t i = 0; i < _countof(FileNameList); i++) { - // Test setting position - dwErrCode = TestArchive_SetPos(hMpq, szFileName1); - if(dwErrCode != ERROR_SUCCESS) - break; + TFileData * pFileData; + LPCSTR szFileName = FileNameList[i]; - // Load the entire file 1 - pFileData1 = LoadMpqFile(&Logger, hMpq, szFileName1); - if(pFileData1 == NULL) + if(szFileName && szFileName[0]) { - dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName1); - break; - } + // Test setting position + dwErrCode = TestArchive_SetPos(hMpq, szFileName); + if(dwErrCode != ERROR_SUCCESS) + break; - // Check the CRC of file1, if available - if(pFileData1->dwCrc32) - { - // Compare the CRC32, if available - dwCrc32 = crc32(0, (Bytef *)pFileData1->FileData, (uInt)pFileData1->dwFileSize); - if(dwCrc32 != pFileData1->dwCrc32) - Logger.PrintError("Warning: CRC32 error on %s", szFileName1); - } - } + // Load the entire file 1 + FileDataList[i] = pFileData = LoadMpqFile(&Logger, hMpq, szFileName); + if(pFileData == NULL) + { + dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName); + break; + } - // If szFileName2 was given, load it - if(szFileName2 && szFileName2[0]) - { - // Load the entire file 2 - pFileData2 = LoadMpqFile(&Logger, hMpq, szFileName2); - if(pFileData2 == NULL) - { - dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName2); - break; + // Check the CRC of file1, if available + if(pFileData->dwCrc32) + { + // Compare the CRC32, if available + dwCrc32 = crc32(0, (Bytef *)pFileData->FileData, (uInt)pFileData->dwFileSize); + if(dwCrc32 != pFileData->dwCrc32) + Logger.PrintError("Warning: CRC32 error on %s", szFileName); + } } } // If two files were given, compare them - if(pFileData1 && pFileData2) + if(FileDataList[0] && FileDataList[1]) { // Compare both files - if(!CompareTwoFiles(&Logger, pFileData1, pFileData2)) + if(!CompareTwoFiles(&Logger, FileDataList[0], FileDataList[1])) { dwErrCode = Logger.PrintError("The file has different size/content of files"); break; @@ -2560,41 +2565,41 @@ static DWORD TestArchive( } // Search the archive - dwErrCode = SearchArchive(&Logger, hMpq, dwSearchFlags, &dwFileCount, OverallMD5); + dwErrCode = SearchArchive(&Logger, hMpq, dwSearchFlags, &dwFileCount, ObtainedMD5); // Shall we check the file count and overall MD5? - if(dwExpectedFileCount != 0) + if(dwFlags & TFLG_COUNT_HASH) { if(dwFileCount != dwExpectedFileCount) { - Logger.PrintMessage("File count mismatch(expected: %u, found:%u)", dwExpectedFileCount, dwFileCount); + Logger.PrintMessage("File count mismatch(expected: %u, found: %u)", dwExpectedFileCount, dwFileCount); dwErrCode = ERROR_CAN_NOT_COMPLETE; - break; } } // Shall we check overall MD5? if(szExpectedMD5 && szExpectedMD5[0]) { - BinaryFromString(szExpectedMD5, ExpectedMD5, MD5_DIGEST_SIZE); - if(memcmp(ExpectedMD5, OverallMD5, MD5_DIGEST_SIZE)) + char szObtainedMD5[0x40]; + + StringFromBinary(ObtainedMD5, MD5_DIGEST_SIZE, szObtainedMD5); + if(_stricmp(szObtainedMD5, szExpectedMD5)) { - Logger.PrintMessage("Extracted files MD5 mismatch"); + Logger.PrintMessage("Extracted files MD5 mismatch (expected: %s, obtained: %s)", szExpectedMD5, szObtainedMD5); dwErrCode = ERROR_CAN_NOT_COMPLETE; - break; } } break; } // Common cleanup - if(pFileData2 != NULL) - STORM_FREE(pFileData2); - if(pFileData1 != NULL) - STORM_FREE(pFileData1); + if(FileDataList[1] != NULL) + STORM_FREE(FileDataList[1]); + if(FileDataList[0] != NULL) + STORM_FREE(FileDataList[0]); if(hMpq != NULL) SFileCloseArchive(hMpq); - return dwErrCode; + return Logger.PrintVerdict(dwErrCode); } // Open an empty archive (found in WoW cache - it's just a header) @@ -2639,15 +2644,17 @@ static DWORD TestOpenArchive_Corrupt(LPCTSTR szPlainName) // Opens a patched MPQ archive -static DWORD TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, int nExpectedPatchCount, bool bExpectedToFail = false) +static DWORD TestArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, DWORD dwFlags) { TLogHelper Logger("OpenPatchedMpqTest", PatchList[0]); HANDLE hMpq; HANDLE hFile; BYTE Buffer[0x100]; + DWORD dwExpectedPatchCount = (dwFlags & TFLG_COUNT_MASK); DWORD dwFileCount = 0; DWORD BytesRead = 0; DWORD dwErrCode; + bool bExpectedToFail = (dwFlags & TFLG_WILL_FAIL) ? true : false; // Open a patched MPQ archive dwErrCode = OpenPatchedArchive(&Logger, &hMpq, PatchList); @@ -2655,7 +2662,7 @@ static DWORD TestOpenArchive_Patched(LPCTSTR PatchList[], LPCSTR szPatchedFile, { // Check patch count if(szPatchedFile != NULL) - dwErrCode = VerifyFilePatchCount(&Logger, hMpq, szPatchedFile, nExpectedPatchCount); + dwErrCode = VerifyFilePatchCount(&Logger, hMpq, szPatchedFile, dwExpectedPatchCount); // Try to open and read the file if(dwErrCode == ERROR_SUCCESS) @@ -4198,6 +4205,9 @@ static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFil //----------------------------------------------------------------------------- // Tables +static LPCTSTR szBliz = _T("ListFile_Blizzard.txt"); +static LPCTSTR szWotI = _T("ListFile_WarOfTheImmortals.txt"); + static const TEST_INFO TestList_StreamOps[] = { {_T("MPQ_2013_v4_alternate-original.MPQ"), NULL, 0}, @@ -4223,54 +4233,69 @@ static const TEST_INFO TestList_MasterMirror[] = static const TEST_INFO Test_Mpqs[] = { - // Correct or damaged archives - {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"}, - {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, 0, "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016) - {_T("MPQ_2018_v1_icon_error.w3m"), NULL, 0, "file00000002.blp"}, - {_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt")}, // File whose archive's (signature) file has flags = 0x90000000 - {_T("MPQ_2012_v2_EmptyMpq.MPQ") }, // Empty archive (found in WoW cache - it's just a header) - {_T("MPQ_2013_v4_EmptyMpq.MPQ") }, // Empty archive (created artificially - it's just a header) - {_T("MPQ_2013_v4_patch-base-16357.MPQ") }, // Empty archive (found in WoW cache - it's just a header) - {_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ") }, // Empty archive (A buggy MPQ with invalid HET entry count) - {_T("MPQ_2002_v1_BlockTableCut.MPQ") }, // Truncated archive - {_T("MPQ_2010_v2_HasUserData.s2ma") }, // MPQ that actually has user data - {_T("MPQ_2014_v1_AttributesOneEntryLess.w3x") }, // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries - {_T("MPQ_2020_v1_AHF04patch.mix") }, // MIX file - {_T("MPQ_2010_v3_expansion-locale-frFR.MPQ") }, // MPQ archive v 3.0 - {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE") }, // Encrypted archive from Starcraft II installer - {_T("MPx_2013_v1_LongwuOnline.mpk") }, // MPK archive from Longwu online - {_T("MPx_2013_v1_WarOfTheImmortals.sqp"), _T("ListFile_WarOfTheImmortals.txt") }, // SQP archive from War of the Immortals - {_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part") }, // Partial MPQ with compressed hash table - {_T("blk4-file://streaming/model.MPQ.0")}, // Archive that is merged with multiple files - {_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x")}, - {_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x")}, - {_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x")}, // Warcraft III map locked by the Spazzler protector - {_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x")}, // Warcraft III map locked by the Spazzler protector - {_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x")}, // Warcraft III map locked by the Spazzler protector - {_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m")}, // Warcraft III map locked by the BOBA protector - {_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x")}, - {_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x")}, - {_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x")}, // Warcraft III map locked by Spazy protector - {_T("MPQ_2015_v1_MessListFile.mpq")}, - {_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x")}, - {_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x")}, - {_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x")}, // Something like Somj 2.0 - {_T("MPQ_2016_v1_WME4_4.w3x")}, // Protector from China (2016-05-27) - {_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x")}, - {_T("MPQ_2016_v1_ProtectedMap_1.4.w3x")}, - {_T("MPQ_2016_v1_KoreanFile.w3m")}, - {_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x")}, // Load map protected by PG1.11.973 - {_T("MPQ_2017_v1_BigDummyFiles.w3x")}, - {_T("MPQ_2017_v1_TildeInFileName.mpq")}, - {_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, 0, "BlueCrystal.mdx"}, - {_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod")}, // Archive that has two fake headers before the real one - {_T("MPQ_2020_v4_NP_Protect_1.s2ma")}, // SC2 map that is protected by the NP_Protect - {_T("MPQ_2020_v4_NP_Protect_2.s2ma")}, // SC2 map that is protected by the NP_Protect + {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"}, + {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, TEST_DATA("255d87a62f3c9518f72cf723a1818946", 221), "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016) + {_T("MPQ_2018_v1_icon_error.w3m"), NULL, TEST_DATA("fcefa25fb50c391e8714f2562d1e10ff", 19), "file00000002.blp"}, + {_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), szBliz, TEST_DATA("5ef18ef9a26b5704d8d46a344d976c89", 2)}, // File whose archive's (signature) file has flags = 0x90000000 + {_T("MPQ_2012_v2_EmptyMpq.MPQ"), NULL, TEST_DATA("00000000000000000000000000000000", 0)}, // Empty archive (found in WoW cache - it's just a header) + {_T("MPQ_2013_v4_EmptyMpq.MPQ"), NULL, TEST_DATA("00000000000000000000000000000000", 0)}, // Empty archive (created artificially - it's just a header) + {_T("MPQ_2013_v4_patch-base-16357.MPQ"), NULL, TEST_DATA("d41d8cd98f00b204e9800998ecf8427e", 1)}, // Empty archive (found in WoW cache - it's just a header) + {_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ"), NULL, TEST_DATA("be4b49ecc3942d1957249f9da0021659", 6)}, // Empty archive (with invalid HET entry count) + {_T("MPQ_2002_v1_BlockTableCut.MPQ"), NULL, TEST_DATA("a9499ab74d939303d8cda7c397c36275", 287)}, // Truncated archive + {_T("MPQ_2010_v2_HasUserData.s2ma"), NULL, TEST_DATA("feff9e2c86db716b6ff5ffc906181200", 52)}, // MPQ that actually has user data + {_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"), NULL, TEST_DATA("90451b7052eb0f1d6f4bf69b2daff7f5", 116)}, // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries + {_T("MPQ_2020_v1_AHF04patch.mix"), NULL, TEST_DATA("d3c6aac48bc12813ef5ce4ad113e58bf", 2891)}, // MIX file + {_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), NULL, TEST_DATA("0c8fc921466f07421a281a05fad08b01", 53)}, // MPQ archive v 3.0 (the only one I know) + {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, TEST_DATA("10e4dcdbe95b7ad731c563ec6b71bc16", 82)}, // Encrypted archive from Starcraft II installer + {_T("MPx_2013_v1_LongwuOnline.mpk"), NULL, TEST_DATA("548f7db88284097f7e94c95a08c5bc24", 469)}, // MPK archive from Longwu online + {_T("MPx_2013_v1_WarOfTheImmortals.sqp"), szWotI, TEST_DATA("a048f37f7c6162a96253d8081722b6d9", 9396)}, // SQP archive from War of the Immortals + {_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"),0, TEST_DATA("d41d8cd98f00b204e9800998ecf8427e", 14263)}, // Partial MPQ with compressed hash table + {_T("blk4-file://streaming/model.MPQ.0"), NULL, TEST_DATA("e06b00efb2fc7e7469dd8b3b859ae15d", 39914)}, // Archive that is merged with multiple files // Protected archives - {_T("MPQ_2015_v1_flem1.w3x"), NULL, TEST_FLAG_PROTECTED | 20, "1c4c13e627658c473e84d94371e31f37"}, - {_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, TEST_FLAG_PROTECTED | 114, "5250975ed917375fc6540d7be436d4de"}, + {_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"), NULL, TEST_DATA("b900364cc134a51ddeca21a13697c3ca", 79)}, + {_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x"), NULL, TEST_DATA("db67e894da9de618a1cdf86d02d315ff", 117)}, + {_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x"), NULL, TEST_DATA("72d7963aa799a7fb4117c55b7beabaf9", 470)}, // Warcraft III map locked by the Spazzler protector + {_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x"), NULL, TEST_DATA("72d7963aa799a7fb4117c55b7beabaf9", 470)}, // Warcraft III map locked by the Spazzler protector + {_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x"), NULL, TEST_DATA("e55aad2dd33cf68b372ca8e30dcb78a7", 130)}, // Warcraft III map locked by the Spazzler protector + {_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m"), NULL, TEST_DATA("7b725d87e07a2173c42fe2314b95fa6c", 17)}, // Warcraft III map locked by the BOBA protector + {_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x"), NULL, TEST_DATA("c7ca4d2d0b1e58db5c784f522506c897", 1578)}, + {_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x"), NULL, TEST_DATA("b411f9a51a6e9a9a509150c8d66ba359", 92)}, + {_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x"), NULL, TEST_DATA("6e491bd055511435dcb4d9c8baed0516", 4089)}, // Warcraft III map locked by Spazy protector + {_T("MPQ_2015_v1_MessListFile.mpq"), NULL, TEST_DATA("15e25d5be124d8ad71519f967997efc2", 8)}, + {_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x"), NULL, TEST_DATA("ad81b43cbd37bbfa27e4bed4c17e6a81", 176)}, + {_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x"), NULL, TEST_DATA("d6e712c275a26dc51f16b3a02f6187df", 228)}, + {_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x"), NULL, TEST_DATA("457cdbf97a9ca41cfe8ea130dafaa0bb", 21)}, // Something like Somj 2.0 + {_T("MPQ_2016_v1_WME4_4.w3x"), NULL, TEST_DATA("e85e1c0ccb4465a30ffd07cae3260254", 382)}, // Protector from China (2016-05-27) + {_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x"), NULL, TEST_DATA("b6f6d56f4f8aaef04c2c4b1f08881a8b", 16)}, + {_T("MPQ_2016_v1_ProtectedMap_1.4.w3x"), NULL, TEST_DATA("3c7908b29d3feac9ec952282390a242d", 5027)}, + {_T("MPQ_2016_v1_KoreanFile.w3m"), NULL, TEST_DATA("805d1f75712472a81c6df27b2a71f946", 18)}, + {_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x"), NULL, TEST_DATA("7a7f0749b47b5f05a8b63ecba2488a3e", 16300)}, // Protected by PG1.11.973 + {_T("MPQ_2017_v1_BigDummyFiles.w3x"), NULL, TEST_DATA("f4d2ee9d85d2c4107e0b2d00ff302dd7", 9086)}, + {_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, TEST_DATA("f203e3979247a4dbf7f3828695ac810c", 5)}, + {_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, TEST_DATA("12c0f4e15c7361b7c13acd37a181d83b", 857), "BlueCrystal.mdx"}, + {_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"), NULL, TEST_DATA("f45392f6523250c943990a017c230b41", 24)}, // Archive that has two fake headers before the real one + {_T("MPQ_2020_v4_NP_Protect_1.s2ma"), NULL, TEST_DATA("1a1ea40ac1165bcdb4f2e434edfc7636", 21)}, // SC2 map that is protected by the NP_Protect + {_T("MPQ_2020_v4_NP_Protect_2.s2ma"), NULL, TEST_DATA("7d1a379da8bd966da1f4fa6e4646049b", 55)}, // SC2 map that is protected by the NP_Protect + {_T("MPQ_2015_v1_flem1.w3x"), NULL, TEST_DATA("1c4c13e627658c473e84d94371e31f37", 20)}, + {_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, TEST_DATA("5250975ed917375fc6540d7be436d4de", 114)}, + {_T("MPQ_2021_v1_CantExtractCHK.scx"), NULL, TEST_DATA("c9a7ded9f93d883b9419a52bec6087f7", 28)}, +}; + +static const TEST_INFO Patched_Mpqs[] = +{ + {NULL, NULL, 0, PatchList_StarCraft, "music\\terran1.wav"}, + {NULL, NULL, 2, PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob"}, + {NULL, NULL, 8, PatchList_WoW_15050, "World\\Model.blob"}, + {NULL, NULL, 0, PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2"}, + {NULL, NULL, 6, PatchList_SC2_32283, "TriggerLibs\\natives.galaxy"}, + {NULL, NULL, 2, PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy"}, + {NULL, NULL, 3, PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml"}, + {NULL, NULL, TFLG_WILL_FAIL, PatchList_SC2_32283_enGB, "Assets\\Textures\\startupimage.dds"}, + {NULL, NULL, 6, PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt"}, + {NULL, NULL, 1, PatchList_HS_3604_enGB, "Hearthstone.exe"}, + {NULL, NULL, 10, PatchList_HS_6898_enGB, "Hearthstone_Data\\Managed\\Assembly-Csharp.dll"} }; //----------------------------------------------------------------------------- @@ -4291,21 +4316,20 @@ int _tmain(int argc, TCHAR * argv[]) // // Tests on a local listfile // - /* + if(dwErrCode == ERROR_SUCCESS) { TestOnLocalListFile(_T("FLAT-MAP:ListFile_Blizzard.txt")); dwErrCode = TestOnLocalListFile(_T("ListFile_Blizzard.txt")); } - */ + // // Open all files from the command line // - TestArchive(_T("e:\\Other.sqp"), NULL, 0, "replay.game.events", NULL); for(int i = 1; i < argc; i++) { - TestOpenArchive_CompactArchive(argv[i], _T("TestArchiveCopy.mpq"), false); + TestArchive(_T("MPQ_2021_v1_CantExtractCHK.scx"), _T("Listfile_Blizzard.txt"), 0, NULL, NULL); } // @@ -4355,13 +4379,34 @@ int _tmain(int argc, TCHAR * argv[]) { for(size_t i = 0; i < _countof(Test_Mpqs); i++) { - dwErrCode = TestArchive(Test_Mpqs[i].szMpqName1, // Plain archive name - Test_Mpqs[i].szMpqName2, // List file (NULL if none) - Test_Mpqs[i].dwFlags, // What exactly to do - Test_Mpqs[i].szFileName1, // The first name of the open file - Test_Mpqs[i].szFileName2); // The second name of the open file - if(dwErrCode != ERROR_SUCCESS) - break; + dwErrCode = TestArchive(Test_Mpqs[i].szMpqName1, // Plain archive name + Test_Mpqs[i].szMpqName2, // List file (NULL if none) + Test_Mpqs[i].dwFlags, // What exactly to do + (LPCSTR)Test_Mpqs[i].param1, // The 1st parameter + (LPCSTR)Test_Mpqs[i].param2); // The 2nd parameter +// if(dwErrCode != ERROR_SUCCESS) +// break; + dwErrCode = ERROR_SUCCESS; + } + } + + // + // Test opening patched archives - correct, damaged, protected + // + + if(dwErrCode == ERROR_SUCCESS) + { + for(size_t i = 0; i < _countof(Patched_Mpqs); i++) + { + LPCTSTR * PatchList = (LPCTSTR *)Patched_Mpqs[i].param1; + LPCSTR szFileName = (LPCSTR)Patched_Mpqs[i].param2; + + dwErrCode = TestArchive_Patched(PatchList, // List of patches + szFileName, // Name of a file + Patched_Mpqs[i].dwFlags); +// if(dwErrCode != ERROR_SUCCESS) +// break; + dwErrCode = ERROR_SUCCESS; } } @@ -4377,50 +4422,6 @@ int _tmain(int argc, TCHAR * argv[]) if(dwErrCode == ERROR_SUCCESS) dwErrCode = TestOpenArchive_Corrupt(_T("MPQ_2013_vX_Battle.net.MPQ")); - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob", 2); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_WoW_15050, "World\\Model.blob", 8); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2", 0); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283, "TriggerLibs\\natives.galaxy", 6); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy", 2); - - // Open a patched archive with new format of BSDIFF patch - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml", 3); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "Assets\\Textures\\startupimage.dds", 0, true); - - // Open a patched archive where the "StreamingBuckets.txt" in the patch doesn't contain MPQ_FILE_PATCH_FILE - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt", 6); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_HS_3604_enGB, "Hearthstone.exe", 1); - - // Open a patched archive - if(dwErrCode == ERROR_SUCCESS) - dwErrCode = TestOpenArchive_Patched(PatchList_HS_6898_enGB, "Hearthstone_Data\\Managed\\Assembly-Csharp.dll", 10); - // Check the opening archive for read-only if(dwErrCode == ERROR_SUCCESS) dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), true); diff --git a/test/TLogHelper.cpp b/test/TLogHelper.cpp index cd10a3c..3d09823 100644 --- a/test/TLogHelper.cpp +++ b/test/TLogHelper.cpp @@ -36,6 +36,9 @@ class TLogHelper DWORD PrintErrorVa(const char * szFormat, ...); DWORD PrintError(const char * szFormat, const char * szFileName = NULL); + // Print final verdict + DWORD PrintVerdict(DWORD dwErrCode = ERROR_SUCCESS); + const char * UserString; unsigned int UserCount; unsigned int UserTotal; @@ -108,33 +111,10 @@ TLogHelper::TLogHelper(const char * szNewMainTitle, const TCHAR * szNewSubTitle1 TLogHelper::~TLogHelper() { - const TCHAR * szSaveSubTitle1 = szSubTitle1; - const TCHAR * szSaveSubTitle2 = szSubTitle2; - TCHAR szSaveMainTitle[0x80]; - - // Set both to NULL so they won't be printed - StringCopy(szSaveMainTitle, _countof(szSaveMainTitle), szMainTitle); - szSubTitle1 = NULL; - szSubTitle2 = NULL; - szMainTitle = NULL; - - // Print the final information - if(szSaveMainTitle != NULL && bMessagePrinted == false) + // Print a verdict, if no verdict was printed yet + if(bMessagePrinted == false) { - if(bDontPrintResult == false) - { - if(szSaveSubTitle1 != NULL && szSaveSubTitle2 != NULL) - PrintMessage(_T("%s (%s+%s) succeeded."), szSaveMainTitle, szSaveSubTitle1, szSaveSubTitle2); - else if(szSaveSubTitle1 != NULL) - PrintMessage(_T("%s (%s) succeeded."), szSaveMainTitle, szSaveSubTitle1); - else - PrintMessage(_T("%s succeeded."), szSaveMainTitle); - } - else - { - PrintProgress(" "); - printf("\r"); - } + PrintVerdict(ERROR_SUCCESS); } #if defined(_MSC_VER) && defined(_DEBUG) @@ -360,19 +340,60 @@ DWORD TLogHelper::PrintError(const char * szFormat, const char * szFileName) return PrintErrorVa(szFormat, szFileName); } +//----------------------------------------------------------------------------- +// Print final verdict + +DWORD TLogHelper::PrintVerdict(DWORD dwErrCode) +{ + LPCTSTR szSaveSubTitle1 = szSubTitle1; + LPCTSTR szSaveSubTitle2 = szSubTitle2; + TCHAR szSaveMainTitle[0x80]; + + // Set both to NULL so they won't be printed + StringCopy(szSaveMainTitle, _countof(szSaveMainTitle), szMainTitle); + szSubTitle1 = NULL; + szSubTitle2 = NULL; + szMainTitle = NULL; + + // Print the final information + if(szSaveMainTitle[0] != 0) + { + if(bDontPrintResult == false) + { + LPCTSTR szVerdict = (dwErrCode == ERROR_SUCCESS) ? _T("succeeded") : _T("failed"); + + if(szSaveSubTitle1 != NULL && szSaveSubTitle2 != NULL) + PrintMessage(_T("%s (%s+%s) %s."), szSaveMainTitle, szSaveSubTitle1, szSaveSubTitle2, szVerdict); + else if(szSaveSubTitle1 != NULL) + PrintMessage(_T("%s (%s) %s."), szSaveMainTitle, szSaveSubTitle1, szVerdict); + else + PrintMessage(_T("%s %s."), szSaveMainTitle, szVerdict); + } + else + { + PrintProgress(" "); + printf("\r"); + } + } + + // Return the error code so the caller can pass it fuhrter + return dwErrCode; +} + //----------------------------------------------------------------------------- // Protected functions #ifdef _UNICODE TCHAR * TLogHelper::CopyFormatCharacter(TCHAR * szBuffer, const TCHAR *& szFormat) { - static const TCHAR * szStringFormat = _T("\"%s\""); - static const TCHAR * szUint64Format = I64u_t; +// static LPCTSTR szStringFormat = _T("\"%s\""); + static LPCTSTR szStringFormat = _T("%s"); + static LPCTSTR szUint64Format = I64u_t; // String format if(szFormat[0] == '%') { - if(szFormat[1] == 's' && szFormat[2] != ')') + if(szFormat[1] == 's') { _tcscpy(szBuffer, szStringFormat); szFormat += 2; -- cgit v1.2.3