aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadislav Zezula <zezula@volny.cz>2020-09-22 17:02:57 +0200
committerLadislav Zezula <zezula@volny.cz>2020-09-22 17:02:57 +0200
commit4a07a5851ca7b2eaab2cdc41ec1e75803f52ccc9 (patch)
treeddfb30557f4b3d3f2cab0634003ac5282148d8c4
parent29fcb13cbaa15097c83273d45a8fb7179390770b (diff)
Added support for NP_Protect protector (SC2 Maps)
-rw-r--r--src/SBaseCommon.cpp1
-rw-r--r--src/SBaseFileTable.cpp85
-rw-r--r--src/SFileOpenArchive.cpp82
-rw-r--r--src/SFileReadFile.cpp3
-rw-r--r--src/StormCommon.h13
-rw-r--r--test/StormTest.cpp760
6 files changed, 479 insertions, 465 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
index fc80dee..a116625 100644
--- a/src/SBaseCommon.cpp
+++ b/src/SBaseCommon.cpp
@@ -945,6 +945,7 @@ void * LoadMpqTable(
// On archives v 1.0, hash table and block table can go beyond EOF.
// Storm.dll reads as much as possible, then fills the missing part with zeros.
// Abused by Spazzler map protector which sets hash table size to 0x00100000
+ // Abused by NP_Protect in MPQs v4 as well
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
{
// Cut the table size
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index 7c9a857..c93920c 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -216,6 +216,28 @@ void SetBits(
//-----------------------------------------------------------------------------
// Support for MPQ header
+static bool VerifyTablePosition64(
+ ULONGLONG MpqOffset, // Position of the MPQ header
+ ULONGLONG TableOffset, // Position of the MPQ table, relative to MPQ header
+ ULONGLONG TableSize, // Size of the MPQ table, in bytes
+ ULONGLONG FileSize) // Size of the entire file, in bytes
+{
+ // Verify overflows
+ if((MpqOffset + TableOffset) < MpqOffset)
+ return false;
+ if((MpqOffset + TableOffset + TableSize) < MpqOffset)
+ return false;
+
+ // Verify sizes
+ if(TableOffset >= FileSize || TableSize >= FileSize)
+ return false;
+ if((MpqOffset + TableOffset) >= FileSize)
+ return false;
+ if((MpqOffset + TableOffset + TableSize) >= FileSize)
+ return false;
+ return true;
+}
+
static ULONGLONG DetermineArchiveSize_V1(
TMPQArchive * ha,
TMPQHeader * pHeader,
@@ -288,6 +310,38 @@ static ULONGLONG DetermineArchiveSize_V2(
return (EndOfMpq - MpqOffset);
}
+static ULONGLONG DetermineArchiveSize_V4(
+ TMPQHeader * pHeader,
+ ULONGLONG /* MpqOffset */,
+ ULONGLONG /* FileSize */)
+{
+ ULONGLONG ArchiveSize = 0;
+ ULONGLONG EndOfTable;
+
+ // This could only be called for MPQs version 4
+ assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_4);
+
+ // Determine the archive size as the greatest of all valid values
+ EndOfTable = pHeader->BetTablePos64 + pHeader->BetTableSize64;
+ if(EndOfTable > ArchiveSize)
+ ArchiveSize = EndOfTable;
+
+ EndOfTable = pHeader->dwHashTablePos + pHeader->dwHashTableSize * sizeof(TMPQHash);
+ if(EndOfTable > ArchiveSize)
+ ArchiveSize = EndOfTable;
+
+ EndOfTable = pHeader->dwBlockTablePos + pHeader->dwBlockTableSize * sizeof(TMPQBlock);
+ if(EndOfTable > ArchiveSize)
+ ArchiveSize = EndOfTable;
+
+ EndOfTable = pHeader->HetTablePos64 + pHeader->HetTableSize64;
+ if(EndOfTable > ArchiveSize)
+ ArchiveSize = EndOfTable;
+
+ // Return the calculated archive size
+ return ArchiveSize;
+}
+
ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset)
{
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
@@ -339,7 +393,7 @@ int ConvertMpqHeaderToFormat4(
ULONGLONG MpqOffset,
ULONGLONG FileSize,
DWORD dwFlags,
- bool bIsWarcraft3Map)
+ MTYPE MapType)
{
TMPQHeader * pHeader = (TMPQHeader *)ha->HeaderData;
ULONGLONG BlockTablePos64 = 0;
@@ -351,8 +405,10 @@ int ConvertMpqHeaderToFormat4(
// If version 1.0 is forced, then the format version is forced to be 1.0
// Reason: Storm.dll in Warcraft III ignores format version value
- if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) || bIsWarcraft3Map)
+ if((dwFlags & MPQ_OPEN_FORCE_MPQ_V1) || (MapType == MapTypeWarcraft3))
wFormatVersion = MPQ_FORMAT_VERSION_1;
+ if(MapType == MapTypeStarcraft2)
+ wFormatVersion = MPQ_FORMAT_VERSION_4;
// Format-specific fixes
switch(wFormatVersion)
@@ -558,6 +614,24 @@ int ConvertMpqHeaderToFormat4(
// If MD5 doesn't match, we ignore this offset
if(!VerifyDataBlockHash(pHeader, MPQ_HEADER_SIZE_V4 - MD5_DIGEST_SIZE, pHeader->MD5_MpqHeader))
return ERROR_FAKE_MPQ_HEADER;
+ if(!VerifyTablePosition64(MpqOffset, pHeader->HiBlockTablePos64, pHeader->HiBlockTableSize64, FileSize))
+ return ERROR_FAKE_MPQ_HEADER;
+
+ // Check for malformed MPQs
+ if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ha->MpqPos + pHeader->ArchiveSize64) != FileSize || (ha->MpqPos + pHeader->HiBlockTablePos64) >= FileSize)
+ {
+ pHeader->wFormatVersion = MPQ_FORMAT_VERSION_4;
+ pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V4;
+ ha->dwFlags |= MPQ_FLAG_MALFORMED;
+ }
+
+ // Recalculate archive size
+ if(ha->dwFlags & MPQ_FLAG_MALFORMED)
+ {
+ // Calculate the archive size
+ pHeader->ArchiveSize64 = DetermineArchiveSize_V4(pHeader, MpqOffset, FileSize);
+ pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64;
+ }
// Calculate the block table position
BlockTablePos64 = MpqOffset + MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
@@ -1327,7 +1401,7 @@ static TMPQHetTable * TranslateHetTable(TMPQHetHeader * pHetHeader)
if(pHetHeader->ExtHdr.dwDataSize >= (sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader)))
{
// Verify the size of the table in the header
- if(pHetHeader->dwTableSize == pHetHeader->ExtHdr.dwDataSize)
+ if(pHetHeader->ExtHdr.dwDataSize >= pHetHeader->dwTableSize)
{
// The size of the HET table must be sum of header, hash and index table size
assert((sizeof(TMPQHetHeader) - sizeof(TMPQExtHeader) + pHetHeader->dwTotalCount + pHetHeader->dwIndexTableSize) == pHetHeader->dwTableSize);
@@ -1597,10 +1671,11 @@ static TMPQBetTable * TranslateBetTable(
if(pBetHeader->ExtHdr.dwDataSize >= (sizeof(TMPQBetHeader) - sizeof(TMPQExtHeader)))
{
// Verify the size of the table in the header
- if(pBetHeader->dwTableSize == pBetHeader->ExtHdr.dwDataSize)
+ if(pBetHeader->ExtHdr.dwDataSize >= pBetHeader->dwTableSize)
{
// The number of entries in the BET table must be the same like number of entries in the block table
- assert(pBetHeader->dwEntryCount == ha->pHeader->dwBlockTableSize);
+ // Note: Ignored if there is no block table
+ //assert(pBetHeader->dwEntryCount == ha->pHeader->dwBlockTableSize);
assert(pBetHeader->dwEntryCount <= ha->dwMaxFileCount);
// The number of entries in the BET table must be the same like number of entries in the HET table
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp
index 7755eaf..2020e56 100644
--- a/src/SFileOpenArchive.cpp
+++ b/src/SFileOpenArchive.cpp
@@ -19,39 +19,53 @@
#define HEADER_SEARCH_BUFFER_SIZE 0x1000
-/*****************************************************************************/
-/* Local functions */
-/*****************************************************************************/
+//-----------------------------------------------------------------------------
+// Local functions
-static bool IsAviFile(DWORD * HeaderData)
+static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer)
{
- DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]);
- DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderData[2]);
- DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderData[3]);
+ LPDWORD HeaderInt32 = (LPDWORD)pbHeaderBuffer;
+ LPCTSTR szExtension;
- // Test for 'RIFF', 'AVI ' or 'LIST'
- return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C);
-}
+ // Don't do any checks if there is not at least 16 bytes
+ if(cbHeaderBuffer > 0x10)
+ {
+ DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderInt32[0]);
+ DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderInt32[1]);
+ DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderInt32[2]);
+ DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderInt32[3]);
-static bool IsWarcraft3Map(DWORD * HeaderData)
-{
- DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]);
- DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderData[1]);
+ // Test for AVI files (Warcraft III cinematics) - 'RIFF', 'AVI ' or 'LIST'
+ if(DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C)
+ return MapTypeAviFile;
- return (DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000);
-}
+ // Check for Starcraft II maps
+ if((szExtension = _tcsrchr(szFileName, _T('.'))) != NULL)
+ {
+ // The "NP_Protect" protector places fake Warcraft III header
+ // into the Starcraft II maps, whilst SC2 maps have no other header but MPQ v4
+ if(!_tcsicmp(szExtension, _T(".s2ma")) || !_tcsicmp(szExtension, _T(".SC2Map")) || !_tcsicmp(szExtension, _T(".SC2Mod")))
+ {
+ return MapTypeStarcraft2;
+ }
+ }
+
+ // Check for Warcraft III maps
+ if(DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000)
+ return MapTypeWarcraft3;
+ }
-static bool IsDllFile(LPBYTE pbHeaderBuffer, size_t cbBytesAvailable)
-{
// MIX files are DLL files that contain MPQ in overlay.
- // Only Warcraft III is able to load them, so we consider them MPQs v 1.0
- if(cbBytesAvailable > 0x200 && pbHeaderBuffer[0] == 'M' && pbHeaderBuffer[1] == 'Z')
+ // Only Warcraft III is able to load them, so we consider them Warcraft III maps
+ if(cbHeaderBuffer > 0x200 && pbHeaderBuffer[0] == 'M' && pbHeaderBuffer[1] == 'Z')
{
- DWORD e_lfanew = *(LPDWORD)(pbHeaderBuffer + 0x3C);
- if(0 < e_lfanew && e_lfanew < 0x10000)
- return true;
+ // Check the value of IMAGE_DOS_HEADER::e_lfanew at offset 0x3C
+ if(0 < HeaderInt32[0x0F] && HeaderInt32[0x0F] < 0x10000)
+ return MapTypeWarcraft3;
}
- return false;
+
+ // No special map type recognized
+ return MapTypeNotRecognized;
}
static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData)
@@ -171,7 +185,7 @@ bool WINAPI SFileOpenArchive(
ULONGLONG FileSize = 0; // Size of the file
LPBYTE pbHeaderBuffer = NULL; // Buffer for searching MPQ header
DWORD dwStreamFlags = (dwFlags & STREAM_FLAGS_MASK);
- bool bIsWarcraft3Map = false;
+ MTYPE MapType = MapTypeNotRecognized;
int nError = ERROR_SUCCESS;
// Verify the parameters
@@ -264,19 +278,15 @@ bool WINAPI SFileOpenArchive(
break;
}
- // There are AVI files from Warcraft III with 'MPQ' extension.
+ // Check whether the file is AVI file or a Warcraft III/Starcraft II map
if(SearchOffset == 0)
{
- if(IsAviFile((DWORD *)pbHeaderBuffer))
+ // Do nothing if the file is an AVI file
+ if((MapType = CheckMapType(szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile)
{
nError = ERROR_AVI_FILE;
break;
}
-
- if (IsWarcraft3Map((DWORD *)pbHeaderBuffer))
- bIsWarcraft3Map = true;
- if (IsDllFile(pbHeaderBuffer, dwBytesAvailable))
- bIsWarcraft3Map = true;
}
// Search the header buffer
@@ -288,7 +298,7 @@ bool WINAPI SFileOpenArchive(
// 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(bIsWarcraft3Map == false && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
+ if(MapType == MapTypeNotRecognized && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
{
if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA)
{
@@ -316,7 +326,7 @@ bool WINAPI SFileOpenArchive(
if(dwHeaderID == ID_MPQ && dwHeaderSize >= MPQ_HEADER_SIZE_V1)
{
// Now convert the header to version 4
- nError = ConvertMpqHeaderToFormat4(ha, SearchOffset, FileSize, dwFlags, bIsWarcraft3Map);
+ nError = ConvertMpqHeaderToFormat4(ha, SearchOffset, FileSize, dwFlags, MapType);
if(nError != ERROR_FAKE_MPQ_HEADER)
{
bSearchComplete = true;
@@ -325,7 +335,7 @@ bool WINAPI SFileOpenArchive(
}
// Check for MPK archives (Longwu Online - MPQ fork)
- if(bIsWarcraft3Map == false && dwHeaderID == ID_MPK)
+ if(MapType == MapTypeNotRecognized && dwHeaderID == ID_MPK)
{
// Now convert the MPK header to MPQ Header version 4
nError = ConvertMpkHeaderToFormat4(ha, FileSize, dwFlags);
@@ -399,7 +409,7 @@ bool WINAPI SFileOpenArchive(
ha->dwFlags |= MPQ_FLAG_LISTFILE_FORCE;
// Remember whether whis is a map for Warcraft III
- if(bIsWarcraft3Map)
+ if(MapType == MapTypeWarcraft3)
ha->dwFlags |= MPQ_FLAG_WAR3_MAP;
// Set the size of file sector
diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp
index a6b3bc4..a693e70 100644
--- a/src/SFileReadFile.cpp
+++ b/src/SFileReadFile.cpp
@@ -344,11 +344,10 @@ static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos
// Give the number of bytes read
*pdwBytesRead = dwToRead;
- return ERROR_SUCCESS;
}
// An error, sorry
- return ERROR_CAN_NOT_COMPLETE;
+ return nError;
}
static int ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead)
diff --git a/src/StormCommon.h b/src/StormCommon.h
index 95b3320..2d51d92 100644
--- a/src/StormCommon.h
+++ b/src/StormCommon.h
@@ -71,6 +71,17 @@
#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo)
//-----------------------------------------------------------------------------
+// MTYPE definition - specifies what kind of MPQ is the map type
+
+typedef enum _MTYPE
+{
+ MapTypeNotRecognized, // The file does not seems to be a map
+ MapTypeAviFile, // The file is actually an AVI file (Warcraft III cinematics)
+ MapTypeWarcraft3, // The file is a Warcraft III map
+ MapTypeStarcraft2 // The file is a Starcraft II map
+} MTYPE, *PMTYPE;
+
+//-----------------------------------------------------------------------------
// MPQ signature information
// Size of each signature type
@@ -227,7 +238,7 @@ TMPQFile * IsValidFileHandle(HANDLE hFile);
ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset);
ULONGLONG CalculateRawSectorOffset(TMPQFile * hf, DWORD dwSectorOffset);
-int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, bool bIsWarcraft3Map);
+int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, MTYPE MapType);
bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash);
diff --git a/test/StormTest.cpp b/test/StormTest.cpp
index 979750c..c0fbe44 100644
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -33,7 +33,19 @@
#endif
//------------------------------------------------------------------------------
-// Defines
+// Local structures
+
+typedef struct _TEST_INFO
+{
+ LPCTSTR szMpqName1;
+ LPCTSTR szMpqName2;
+ DWORD dwFlags;
+ LPCSTR szFileName1;
+ LPCSTR szFileName2;
+} TEST_INFO, PTEST_INFO;
+
+//------------------------------------------------------------------------------
+// Local variables
#ifdef PLATFORM_WINDOWS
#define WORK_PATH_ROOT _T("\\Multimedia\\MPQs")
@@ -840,75 +852,6 @@ static int FindFiles(FIND_FILE_CALLBACK pfnFindFile, LPCTSTR szSubDirectory)
return FindFilesInternal(pfnFindFile, szWorkBuff);
}
-static int FindFilePairsInternal(
- FIND_PAIR_CALLBACK pfnFilePair,
- TCHAR * szSource,
- TCHAR * szTarget)
-{
- TCHAR * szPlainName1;
- TCHAR * szPlainName2;
- int nError = ERROR_SUCCESS;
-
- // Setup the search masks
- _tcscat(szSource, _T("\\*"));
- szPlainName1 = _tcsrchr(szSource, '*');
- _tcscat(szTarget, _T("\\*"));
- szPlainName2 = _tcsrchr(szTarget, '*');
-
- // If both paths are OK, perform the search
- if(szPlainName1 != NULL && szPlainName2 != NULL)
- {
-#ifdef PLATFORM_WINDOWS
- WIN32_FIND_DATA wf;
- HANDLE hFind;
-
- // Search the second directory
- hFind = FindFirstFile(szTarget, &wf);
- if(hFind != INVALID_HANDLE_VALUE)
- {
- // Skip the first entry, since it's always "." or ".."
- while(FindNextFile(hFind, &wf) && nError == ERROR_SUCCESS)
- {
- // Found a directory?
- if(wf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- if(wf.cFileName[0] != '.')
- {
- _tcscpy(szPlainName1, wf.cFileName);
- _tcscpy(szPlainName2, wf.cFileName);
- nError = FindFilePairsInternal(pfnFilePair, szSource, szTarget);
- }
- }
- else
- {
- if(pfnFilePair != NULL)
- {
- _tcscpy(szPlainName1, wf.cFileName);
- _tcscpy(szPlainName2, wf.cFileName);
- nError = pfnFilePair(szSource, szTarget);
- }
- }
- }
-
- FindClose(hFind);
- }
-#endif
- }
-
- return nError;
-}
-
-static int FindFilePairs(FIND_PAIR_CALLBACK pfnFindPair, LPCTSTR szSourceSubDir, LPCTSTR szTargetSubDir)
-{
- TCHAR szSource[MAX_PATH];
- TCHAR szTarget[MAX_PATH];
-
- // Create the source search mask
- CreateFullPathName(szSource, _countof(szSource), szSourceSubDir, NULL);
- CreateFullPathName(szTarget, _countof(szTarget), szTargetSubDir, NULL);
- return FindFilePairsInternal(pfnFindPair, szSource, szTarget);
-}
-
static int InitializeMpqDirectory(TCHAR * argv[], int argc)
{
TLogHelper Logger("InitWorkDir");
@@ -2314,31 +2257,6 @@ static int TestReadFile_MasterMirror(LPCTSTR szMirrorName, LPCTSTR szMasterName,
}
// Test of the TFileStream object
-static int TestSparseCompression()
-{
- BYTE InpBuffer[0x1000];
- BYTE Compressed[0x1000];
- BYTE Decompressed[0x1000];
- int cbCompressed = sizeof(Compressed);
- int cbDecompressed = sizeof(Compressed);
-
- // Prepare compressed buffer
- memset(InpBuffer, 0, sizeof(InpBuffer));
-
- // Compress and decompress
- CompressSparse(Compressed, &cbCompressed, InpBuffer, sizeof(InpBuffer));
- DecompressSparse(Decompressed, &cbDecompressed, Compressed, cbCompressed);
-
- // Check the result of decompression
- if(cbDecompressed != sizeof(InpBuffer))
- return ERROR_FILE_CORRUPT;
- if(memcmp(Decompressed, InpBuffer, sizeof(InpBuffer)))
- return ERROR_FILE_CORRUPT;
-
- return ERROR_SUCCESS;
-}
-
-// Test of the TFileStream object
static int TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags)
{
TFileStream * pStream = NULL;
@@ -2461,6 +2379,16 @@ static int TestFileStreamOperations(LPCTSTR szPlainName, DWORD dwStreamFlags)
return nError;
}
+static DWORD TestArchive(
+ LPCTSTR szPlainName, // Plain name of the MPQ
+ LPCTSTR szListFile,
+ DWORD dwWhatToDo,
+ LPCSTR szFileName1,
+ LPCSTR szFileName2)
+{
+ return ERROR_CAN_NOT_COMPLETE;
+}
+
static int TestOpenFile_OpenById(LPCTSTR szPlainName)
{
TLogHelper Logger("OpenFileById", szPlainName);
@@ -4329,77 +4257,44 @@ static int TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFileN
}
//-----------------------------------------------------------------------------
-// Comparing two directories, creating links
+// Tables
-#define LINK_COMPARE_BLOCK_SIZE 0x200
-/*
-static int CreateArchiveLinkFile(LPCTSTR szFullPath1, LPCTSTR szFullPath2, LPCSTR szFileHash)
+static const TEST_INFO TestList_StreamOps[] =
{
- TFileStream * pStream;
- TCHAR szLinkData[MAX_PATH + 0x80];
- TCHAR szLinkFile[MAX_PATH];
- TCHAR szLinkPath[MAX_PATH];
- int nLength;
- int nError = ERROR_SUCCESS;
-
- // Construct the link file name
- CalculateRelativePath(szFullPath1, szFullPath2, szLinkPath);
- sprintf(szLinkFile, "%s.link", szFullPath2);
-
- // Format the content of the link file
- nLength = sprintf(szLinkData, "LINK:%s\x0D\x0ASHA1:%s", szLinkPath, szFileHash);
-
- // Create the link file
- pStream = FileStream_CreateFile(szLinkFile, 0);
- if(pStream == NULL)
- return GetLastError();
-
- // Write the content of the link file
- if(!FileStream_Write(pStream, NULL, szLinkData, (DWORD)nLength))
- nError = GetLastError();
-
- FileStream_Close(pStream);
- return ERROR_SUCCESS;
-}
+ {_T("MPQ_2013_v4_alternate-original.MPQ"), NULL, 0},
+ {_T("MPQ_2013_v4_alternate-original.MPQ"), NULL, STREAM_FLAG_READ_ONLY},
+ {_T("MPQ_2013_v4_alternate-complete.MPQ"), NULL, STREAM_FLAG_USE_BITMAP},
+ {_T("part-file://MPQ_2009_v2_WoW_patch.MPQ.part"), NULL, 0},
+ {_T("blk4-file://streaming/model.MPQ.0"), NULL, STREAM_PROVIDER_BLOCK4},
+ {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, STREAM_PROVIDER_MPQE}
+};
-static int ForEachFile_CreateArchiveLink(LPCTSTR szFullPath1, LPCTSTR szFullPath2)
+static const TEST_INFO TestList_MasterMirror[] =
{
- TLogHelper Logger("CreateMpqLink");
- TCHAR szFileHash1[0x40];
- TCHAR szFileHash2[0x40];
- int nError;
+ {_T("part-file://MPQ_2009_v1_patch-created.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), 0},
+ {_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), 1},
+ {_T("part-file://MPQ_2009_v1_patch-complete.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), 1},
+ {_T("MPQ_2013_v4_alternate-created.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), 0},
+ {_T("MPQ_2013_v4_alternate-incomplete.MPQ"), _T("MPQ_2013_v4_alternate-incomplete.MPQ"), 1},
+ {_T("MPQ_2013_v4_alternate-complete.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), 1},
+
+ // Takes hell a lot of time!!!
+// {_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("http://www.zezula.net\\mpqs\\alternate.zip"), 0}
+};
- // Prevent logger from witing any result messages
- Logger.bDontPrintResult = true;
+#define TEST_OPEN_COMPARE_TWO_FILES 0x01
- // Create SHA1 of both files
- nError = CalculateFileSha1(&Logger, szFullPath1, szFileHash1);
- if(nError == ERROR_SUCCESS)
- {
- nError = CalculateFileSha1(&Logger, szFullPath2, szFileHash2);
- if(nError == ERROR_SUCCESS)
- {
- // If the hashes are identical, we can create link
- if(!_tcscmp(szFileHash1, szFileHash2))
- {
- nError = CreateArchiveLinkFile(szFullPath1, szFullPath2, szFileHash1);
- if(nError == ERROR_SUCCESS)
- {
- Logger.PrintMessage("Created link to %s", szFullPath2);
- }
- }
- }
- }
+static const TEST_INFO Test_Mpqs[] =
+{
+ {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, TEST_OPEN_COMPARE_TWO_FILES, "music\\dintro.wav", "File00000023.xxx"},
+};
- return ERROR_SUCCESS;
-}
-*/
//-----------------------------------------------------------------------------
// Main
int _tmain(int argc, TCHAR * argv[])
{
- int nError = ERROR_SUCCESS;
+ DWORD dwErrCode = ERROR_SUCCESS;
#if defined(_MSC_VER) && defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
@@ -4407,469 +4302,492 @@ int _tmain(int argc, TCHAR * argv[])
// Initialize storage and mix the random number generator
printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING);
- nError = InitializeMpqDirectory(argv, argc);
+ dwErrCode = InitializeMpqDirectory(argv, argc);
- SFILE_FIND_DATA sf;
- HANDLE hFind = NULL;
- HANDLE hMpq = NULL;
- if(SFileOpenArchive(_T("e:\\Ladik\\Incoming\\mpq-issue\\SampleB-by861.SC2Map"), 0, MPQ_OPEN_FORCE_LISTFILE, &hMpq))
+ // Open all files from the command line
+ for(int i = 1; i < argc; i++)
{
- if((hFind = SFileFindFirstFile(hMpq, "*", &sf, NULL)) != NULL)
+ SFILE_FIND_DATA sf;
+ HANDLE hFile = NULL;
+ HANDLE hMpq = NULL;
+ BYTE Buffer[0x40];
+
+ if(SFileOpenArchive(argv[i], 0, 0, &hMpq))
{
- SFileFindNextFile(hFind, &sf);
- SFileFindClose(hFind);
- }
+ if(SFileOpenFileEx(hMpq, "koKR.SC2Data\\LocalizedData\\ObjectStrings.txt", 0, &hFile))
+ {
+ SFileReadFile(hFile, Buffer, sizeof(Buffer), NULL, NULL);
+ SFileCloseFile(hFile);
+ }
- SFileCloseArchive(hMpq);
+ //if((hFind = SFileFindFirstFile(hMpq, "*", &sf, NULL)) != NULL)
+ //{
+ // SFileFindNextFile(hFind, &sf);
+ // SFileFindClose(hFind);
+ //}
+
+ SFileCloseArchive(hMpq);
+ }
}
- // Not a test, but rather a tool for creating links to duplicated files
-// if(nError == ERROR_SUCCESS)
-// nError = FindFilePairs(ForEachFile_CreateArchiveLink, "2004 - WoW\\06080", "2004 - WoW\\06299");
-/*
+ //
// Search all testing archives and verify their SHA1 hash
- if(nError == ERROR_SUCCESS)
- nError = FindFiles(ForEachFile_VerifyFileChecksum, szMpqSubDir);
-
- // Test sparse compression
- if(nError == ERROR_SUCCESS)
- nError = TestSparseCompression();
-
- // Test reading linear file without bitmap
- if(nError == ERROR_SUCCESS)
- nError = TestFileStreamOperations(_T("MPQ_2013_v4_alternate-original.MPQ"), 0);
-
- // Test reading linear file without bitmap (read only)
- if(nError == ERROR_SUCCESS)
- nError = TestFileStreamOperations(_T("MPQ_2013_v4_alternate-original.MPQ"), STREAM_FLAG_READ_ONLY);
-
- // Test reading linear file with bitmap
- if(nError == ERROR_SUCCESS)
- nError = TestFileStreamOperations(_T("MPQ_2013_v4_alternate-complete.MPQ"), STREAM_FLAG_USE_BITMAP);
-
- // Test reading partial file
- if(nError == ERROR_SUCCESS)
- nError = TestFileStreamOperations(_T("part-file://MPQ_2009_v2_WoW_patch.MPQ.part"), 0);
-
- // Test reading Block4K file
- if(nError == ERROR_SUCCESS)
- nError = TestFileStreamOperations(_T("blk4-file://streaming/model.MPQ.0"), STREAM_PROVIDER_BLOCK4);
-
- // Test reading encrypted file
- if(nError == ERROR_SUCCESS)
- nError = TestFileStreamOperations(_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), STREAM_PROVIDER_MPQE);
-
- // Open a stream, paired with local master. The mirror file is created new
- if(nError == ERROR_SUCCESS)
- nError = TestReadFile_MasterMirror(_T("part-file://MPQ_2009_v1_patch-created.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), false);
-
- // Open a stream, paired with local master. Only part of the mirror exists
- if(nError == ERROR_SUCCESS)
- nError = TestReadFile_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), true);
+ //
- // Open a stream, paired with local master. Only part of the mirror exists
- if(nError == ERROR_SUCCESS)
- nError = TestReadFile_MasterMirror(_T("part-file://MPQ_2009_v1_patch-complete.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), true);
+ //if(dwErrCode == ERROR_SUCCESS)
+ //{
+ // dwErrCode = FindFiles(ForEachFile_VerifyFileChecksum, szMpqSubDir);
+ //}
- // Open a stream, paired with local master
- if(nError == ERROR_SUCCESS)
- nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-created.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), false);
+ //
+ // Test file stream operations
+ //
- // Open a stream, paired with local master
- if(nError == ERROR_SUCCESS)
- nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-incomplete.MPQ"), _T("MPQ_2013_v4_alternate-incomplete.MPQ"), true);
+ if(dwErrCode == ERROR_SUCCESS)
+ {
+ for(size_t i = 0; i < _countof(TestList_StreamOps); i++)
+ {
+ dwErrCode = TestFileStreamOperations(TestList_StreamOps[i].szMpqName1, TestList_StreamOps[i].dwFlags);
+ if(dwErrCode != ERROR_SUCCESS)
+ break;
+ }
+ }
- // Open a stream, paired with local master
- if(nError == ERROR_SUCCESS)
- nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-complete.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), true);
+ //
+ // Test master-mirror reading operations
+ //
- // Open a stream, paired with remote master (takes hell lot of time!!!)
-// if(nError == ERROR_SUCCESS)
-// nError = TestReadFile_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("http://www.zezula.net\\mpqs\\alternate.zip"), false);
+ if(dwErrCode == ERROR_SUCCESS)
+ {
+ for(size_t i = 0; i < _countof(TestList_MasterMirror); i++)
+ {
+ dwErrCode = TestReadFile_MasterMirror(TestList_MasterMirror[i].szMpqName1,
+ TestList_MasterMirror[i].szMpqName2,
+ TestList_MasterMirror[i].dwFlags != 0);
+ if(dwErrCode != ERROR_SUCCESS)
+ break;
+ }
+ }
+ //
// Search in listfile
- if(nError == ERROR_SUCCESS)
- nError = TestSearchListFile(_T("ListFile_Blizzard.txt"));
+ //
+
+ if(dwErrCode == ERROR_SUCCESS)
+ {
+ dwErrCode = TestSearchListFile(_T("ListFile_Blizzard.txt"));
+ }
+ //
// Test opening local file with SFileOpenFileEx
- if(nError == ERROR_SUCCESS)
- nError = TestOpenLocalFile(_T("ListFile_Blizzard.txt"));
+ //
+ if(dwErrCode == ERROR_SUCCESS)
+ {
+ dwErrCode = TestOpenLocalFile(_T("ListFile_Blizzard.txt"));
+ }
+
+ //
+ // Test opening various archives - correct, damaged, protected
+ //
+/*
+ if(dwErrCode == ERROR_SUCCESS)
+ {
+ 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;
+ }
+ }
+*/
// Test working with an archive that has no listfile
- if(nError == ERROR_SUCCESS)
- nError = TestOpenFile_OpenById(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenFile_OpenById(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"));
// Open the update MPQ from Diablo II (patch 2016)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenFile_OpenByName(_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), "waitingroombkgd.dc6");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenFile_OpenByName(_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), "waitingroombkgd.dc6");
- if(nError == ERROR_SUCCESS)
- nError = TestOpenFile_OpenByName(_T("MPQ_2018_v1_icon_error.w3m"), "file00000002.blp");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenFile_OpenByName(_T("MPQ_2018_v1_icon_error.w3m"), "file00000002.blp");
// Open a file whose archive's (signature) file has flags = 0x90000000
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
// Test the SFileSetFilePointer operations
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_SetPos(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), "music\\dtowne.wav");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_SetPos(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), "music\\dtowne.wav");
// Open an empty archive (found in WoW cache - it's just a header)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2012_v2_EmptyMpq.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2012_v2_EmptyMpq.MPQ"));
// Open an empty archive (created artificially - it's just a header)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2013_v4_EmptyMpq.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2013_v4_EmptyMpq.MPQ"));
// Open an empty archive (found in WoW cache - it's just a header)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2013_v4_patch-base-16357.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2013_v4_patch-base-16357.MPQ"));
// Open an empty archive (A buggy MPQ with invalid HET entry count)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2011_v4_InvalidHetEntryCount.MPQ"));
// Open a truncated archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2002_v1_BlockTableCut.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2002_v1_BlockTableCut.MPQ"));
// Open a MPQ that actually has user data
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2010_v2_HasUserData.s2ma"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2010_v2_HasUserData.s2ma"));
// Open a file whose archive's (signature) file has flags = 0x90000000
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("ListFile_Blizzard.txt"));
// Open an Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"));
// Open a MIX file
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2020_v1_AHF04patch.mix"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2020_v1_AHF04patch.mix"));
// Open a MPQ archive v 3.0
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"));
// Open an encrypted archive from Starcraft II installer
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"));
// Open a MPK archive from Longwu online
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPx_2013_v1_LongwuOnline.mpk"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPx_2013_v1_LongwuOnline.mpk"));
// Open a SQP archive from War of the Immortals
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPx_2013_v1_WarOfTheImmortals.sqp"), _T("ListFile_WarOfTheImmortals.txt"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPx_2013_v1_WarOfTheImmortals.sqp"), _T("ListFile_WarOfTheImmortals.txt"));
// Open a partial MPQ with compressed hash table
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"));
// Open an protected map
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_ProtectedMap(_T("MPQ_2015_v1_flem1.w3x"), NULL, 20, "1c4c13e627658c473e84d94371e31f37");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_ProtectedMap(_T("MPQ_2015_v1_flem1.w3x"), NULL, 20, "1c4c13e627658c473e84d94371e31f37");
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_ProtectedMap(_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, 114, "5250975ed917375fc6540d7be436d4de");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_ProtectedMap(_T("MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x"), NULL, 114, "5250975ed917375fc6540d7be436d4de");
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x"));
// Open an Warcraft III map locked by the Spazzler protector
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_Spazzler.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2014_v1_ProtectedMap_Spazzler2.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2014_v1_ProtectedMap_Spazzler3.w3x"));
// Open an Warcraft III map locked by the BOBA protector
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2002_v1_ProtectedMap_BOBA.w3m"));
// Open an Warcraft III map locked by a protector
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_KangTooJee.w3x"));
// Open an Warcraft III map locked by a protector
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x"));
// Open an Warcraft III map locked by Spazy protector
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2015_v1_ProtectedMap_Spazy.w3x"));
// Open an Warcraft III map locked by Spazy protector
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2015_v1_MessListFile.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2015_v1_MessListFile.mpq"));
// Open another protected map
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x"));
// Open another protected map
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x"));
// Something like Somj 2.0
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_Somj2.w3x"));
// Protector from China (2016-05-27)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_WME4_4.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_WME4_4.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_SP_(4)Adrenaline.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_1.4.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_ProtectedMap_1.4.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2016_v1_KoreanFile.w3m"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2016_v1_KoreanFile.w3m"));
// Load map protected by PG1.11.973
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x"));
// Load map protected by PG1.11.973
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2017_v1_BigDummyFiles.w3x"), NULL, "1.blp");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2017_v1_BigDummyFiles.w3x"), NULL, "1.blp");
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, "1.blp");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2017_v1_TildeInFileName.mpq"), NULL, "1.blp");
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, "BlueCrystal.mdx");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2018_v1_EWIX_v8_7.w3x"), NULL, "BlueCrystal.mdx");
// Open the multi-file archive with wrong prefix to see how StormLib deals with it
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_WillFail(_T("flat-file://streaming/model.MPQ.0"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_WillFail(_T("flat-file://streaming/model.MPQ.0"));
// Open an archive that is merged with multiple files
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("blk4-file://streaming/model.MPQ.0"), NULL, NULL, true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("blk4-file://streaming/model.MPQ.0"), NULL, NULL, true);
// Open every MPQ that we have in the storage
- if(nError == ERROR_SUCCESS)
- nError = FindFiles(ForEachFile_OpenArchive, NULL);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = FindFiles(ForEachFile_OpenArchive, NULL);
// Test on an archive that has been invalidated by extending an old valid MPQ
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Corrupt(_T("MPQ_2013_vX_Battle.net.MPQ"));
-*/
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Corrupt(_T("MPQ_2013_vX_Battle.net.MPQ"));
+
// Test on an archive that has two fake headers before the real one
- if (nError == ERROR_SUCCESS)
- nError = TestOpenArchive(_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"));
+ if (dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"));
+
+ // Test on an SC2 map that is protected by the NP_Protect
+ if (dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2020_v4_NP_Protect_1.s2ma"));
+
+ // Test on an SC2 map that is protected by the NP_Protect
+ if (dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive(_T("MPQ_2020_v4_NP_Protect_2.s2ma"));
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob", 2);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_WoW_OldWorld13286, "OldWorld\\World\\Model.blob", 2);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_WoW_15050, "World\\Model.blob", 8);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_WoW_15050, "World\\Model.blob", 8);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2", 0);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_WoW_16965, "DBFilesClient\\BattlePetNPCTeamMember.db2", 0);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_SC2_32283, "TriggerLibs\\natives.galaxy", 6);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283, "TriggerLibs\\natives.galaxy", 6);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_SC2_34644, "TriggerLibs\\GameData\\GameData.galaxy", 2);
+ 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(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml", 3);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_SC2_34644_Maps, "Maps\\Campaign\\THorner03.SC2Map\\BankList.xml", 3);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "LocalizedData\\GameHotkeys.txt", 0, true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_SC2_32283_enGB, "LocalizedData\\GameHotkeys.txt", 0, true);
// Open a patched archive where the "StreamingBuckets.txt" in the patch doesn't contain MPQ_FILE_PATCH_FILE
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt", 6);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_SC2_36281_enGB, "LocalizedData\\GameHotkeys.txt", 6);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_HS_3604_enGB, "Hearthstone.exe", 1);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_Patched(PatchList_HS_3604_enGB, "Hearthstone.exe", 1);
// Open a patched archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Patched(PatchList_HS_6898_enGB, "Hearthstone_Data\\Managed\\Assembly-Csharp.dll", 10);
+ 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(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), true);
// Check the opening archive for read-only
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_ReadOnly(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false);
// Check the SFileGetFileInfo function
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_GetFileInfo(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_GetFileInfo(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"));
// Downloadable MPQ archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), "world\\Azeroth\\DEADMINES\\PASSIVEDOODADS\\GOBLINMELTINGPOT\\DUST2.BLP", false);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_MasterMirror(_T("part-file://MPQ_2009_v1_patch-partial.MPQ.part"), _T("MPQ_2009_v1_patch-original.MPQ"), "world\\Azeroth\\DEADMINES\\PASSIVEDOODADS\\GOBLINMELTINGPOT\\DUST2.BLP", false);
// Downloadable MPQ archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), "alternate\\DUNGEONS\\TEXTURES\\ICECROWN\\GATE\\jlo_IceC_Floor_Thrown.blp", false);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_MasterMirror(_T("MPQ_2013_v4_alternate-downloaded.MPQ"), _T("MPQ_2013_v4_alternate-original.MPQ"), "alternate\\DUNGEONS\\TEXTURES\\ICECROWN\\GATE\\jlo_IceC_Floor_Thrown.blp", false);
// Check archive signature
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_VerifySignature(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("STANDARD.SNP"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), _T("STANDARD.SNP"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_VerifySignature(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_VerifySignature(_T("MPQ_2003_v1_WeakSignatureEmpty.exe"), _T("WoW-1.2.3.4211-enUS-patch.exe"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_2003_v1_WeakSignatureEmpty.exe"), _T("WoW-1.2.3.4211-enUS-patch.exe"));
// Check archive signature
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_VerifySignature(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("(10)DustwallowKeys.w3m"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_VerifySignature(_T("MPQ_2002_v1_StrongSignature.w3m"), _T("(10)DustwallowKeys.w3m"));
// Compact the archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_CompactArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), _T("StormLibTest_CraftedMpq1_v3.mpq"), true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), _T("StormLibTest_CraftedMpq1_v3.mpq"), true);
// Compact the archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_CompactArchive(_T("MPQ_2016_v1_00000.pak"), _T("MPQ_2016_v1_00000.pak"), false);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2016_v1_00000.pak"), _T("MPQ_2016_v1_00000.pak"), false);
// Open a MPQ (add custom user data to it)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), _T("StormLibTest_CraftedMpq2_v4.mpq"), true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), _T("StormLibTest_CraftedMpq2_v4.mpq"), true);
// Open a MPQ (add custom user data to it)
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_expansion1.MPQ"), _T("StormLibTest_CraftedMpq3_v4.mpq"), true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_CompactArchive(_T("MPQ_2013_v4_expansion1.MPQ"), _T("StormLibTest_CraftedMpq3_v4.mpq"), true);
- if(nError == ERROR_SUCCESS)
- nError = TestAddFile_FullTable(_T("MPQ_2014_v1_out1.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestAddFile_FullTable(_T("MPQ_2014_v1_out1.w3x"));
- if(nError == ERROR_SUCCESS)
- nError = TestAddFile_FullTable(_T("MPQ_2014_v1_out2.w3x"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestAddFile_FullTable(_T("MPQ_2014_v1_out2.w3x"));
// Test modifying file with no (listfile) and no (attributes)
- if(nError == ERROR_SUCCESS)
- nError = TestAddFile_ListFileTest(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false, false);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestAddFile_ListFileTest(_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), false, false);
// Test modifying an archive that contains (listfile) and (attributes)
- if(nError == ERROR_SUCCESS)
- nError = TestAddFile_ListFileTest(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), true, true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestAddFile_ListFileTest(_T("MPQ_2013_v4_SC2_EmptyMap.SC2Map"), true, true);
// Create an empty archive v2
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v2.mpq"), MPQ_CREATE_ARCHIVE_V2 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v2.mpq"), MPQ_CREATE_ARCHIVE_V2 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
// Create an empty archive v4
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v4.mpq"), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_EmptyMpq(_T("StormLibTest_EmptyMpq_v4.mpq"), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES);
// Test creating of an archive the same way like MPQ Editor does
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_TestGaps(_T("StormLibTest_GapsTest.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_TestGaps(_T("StormLibTest_GapsTest.mpq"));
// Test creating of an archive with non standard file names
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_NonStdNames(_T("StormLibTest_NonStdNames.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_NonStdNames(_T("StormLibTest_NonStdNames.mpq"));
// Sign an existing non-signed archive
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_SignExisting(_T("MPQ_1998_v1_StarDat.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_SignExisting(_T("MPQ_1998_v1_StarDat.mpq"));
// Open a signed archive, add a file and verify the signature
- if(nError == ERROR_SUCCESS)
- nError = TestOpenArchive_ModifySigned(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_ModifySigned(_T("MPQ_1999_v1_WeakSignature.exe"), _T("War2Patch_202.exe"));
// Create new archive and sign it
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned1.mpq"), true);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned1.mpq"), true);
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned2.mpq"), false);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_Signed(_T("MPQ_1999_v1_WeakSigned2.mpq"), false);
// Test creating of an archive the same way like MPQ Editor does
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_MpqEditor(_T("StormLibTest_MpqEditorTest.mpq"), "AddedFile.exe");
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_MpqEditor(_T("StormLibTest_MpqEditorTest.mpq"), "AddedFile.exe");
// Create an archive and fill it with files up to the max file count
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), 0);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), 0);
// Create an archive and fill it with files up to the max file count
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_LISTFILE);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_LISTFILE);
// Create an archive and fill it with files up to the max file count
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES);
// Create an archive and fill it with files up to the max file count
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_LISTFILE);
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_FillArchive(_T("StormLibTest_FileTableFull.mpq"), MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_LISTFILE);
// Create an archive, and increment max file count several times
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_IncMaxFileCount(_T("StormLibTest_IncMaxFileCount.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_IncMaxFileCount(_T("StormLibTest_IncMaxFileCount.mpq"));
// Create a MPQ archive with UNICODE names
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_UnicodeNames();
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_UnicodeNames();
// Create a MPQ file, add files with various flags
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_FileFlagTest(_T("StormLibTest_FileFlagTest.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_FileFlagTest(_T("StormLibTest_FileFlagTest.mpq"));
// Create a MPQ file, add a mono-WAVE file with various compressions
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoTest.mpq"), _T("AddFile-Mono.wav"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoTest.mpq"), _T("AddFile-Mono.wav"));
// Create a MPQ file, add a mono-WAVE with 8 bits per sample file with various compressions
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoBadTest.mpq"), _T("AddFile-MonoBad.wav"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveMonoBadTest.mpq"), _T("AddFile-MonoBad.wav"));
// Create a MPQ file, add a stereo-WAVE file with various compressions
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveStereoTest.mpq"), _T("AddFile-Stereo.wav"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_WaveCompressionsTest(_T("StormLibTest_AddWaveStereoTest.mpq"), _T("AddFile-Stereo.wav"));
// Check if the listfile is always created at the end of the file table in the archive
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_ListFilePos(_T("StormLibTest_ListFilePos.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_ListFilePos(_T("StormLibTest_ListFilePos.mpq"));
// Open a MPQ (add custom user data to it)
- if(nError == ERROR_SUCCESS)
- nError = TestCreateArchive_BigArchive(_T("StormLibTest_BigArchive_v4.mpq"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestCreateArchive_BigArchive(_T("StormLibTest_BigArchive_v4.mpq"));
// Test replacing a file with zero size file
- if(nError == ERROR_SUCCESS)
- nError = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events"));
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events"));
#ifdef _MSC_VER
_CrtDumpMemoryLeaks();
#endif // _MSC_VER
- return nError;
+ return dwErrCode;
}