aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadislav Zezula <zezula@volny.cz>2022-10-03 20:06:22 +0200
committerGitHub <noreply@github.com>2022-10-03 20:06:22 +0200
commit3846f0b8e2c47320c6b499492496f3e3f2e76821 (patch)
tree59610e60d94b65d8439d979802a5852d9b48c745
parent88b18d4d097ef6cabb4f99f3a48db172064ea119 (diff)
parent305583053bf2796adf3162cf617020c250d7faf7 (diff)
Merge pull request #265 from ladislav-zezula/LZ_LocaleAndPlatformv9.24
Locale&platform problems fixed
-rw-r--r--make-msvc.bat8
-rw-r--r--src/SBaseCommon.cpp17
-rw-r--r--src/SBaseDumpData.cpp2
-rw-r--r--src/SBaseFileTable.cpp54
-rw-r--r--src/SBaseSubTypes.cpp7
-rw-r--r--src/SFileAddFile.cpp20
-rw-r--r--src/SFileFindFile.cpp4
-rw-r--r--src/SFileGetFileInfo.cpp2
-rw-r--r--src/SFileListFile.cpp2
-rw-r--r--src/SFileOpenArchive.cpp5
-rw-r--r--src/SFileOpenFileEx.cpp8
-rw-r--r--src/StormCommon.h14
-rw-r--r--src/StormLib.h22
-rw-r--r--test/StormTest.cpp88
-rw-r--r--test/stormlib-test.txt25
15 files changed, 160 insertions, 118 deletions
diff --git a/make-msvc.bat b/make-msvc.bat
index 1a22835..80d99fe 100644
--- a/make-msvc.bat
+++ b/make-msvc.bat
@@ -21,10 +21,10 @@ if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Professional\VC\Auxil
if exist "%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" set VCVARS_2019=%PROGRAM_FILES_DIR%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat
:: Build all libraries using Visual Studio 2008 and 2019
-call :BuildLibs "%VCVARS_2008%" x86 %LIB_NAME%_vs08.sln \vs2008
-call :BuildLibs "%VCVARS_2008%" x64 %LIB_NAME%_vs08.sln \vs2008
-call :BuildLibs "%VCVARS_2019%" x86 %LIB_NAME%_vs19.sln
-call :BuildLibs "%VCVARS_2019%" x64 %LIB_NAME%_vs19.sln
+if not "x%VCVARS_2008%" == "x" call :BuildLibs "%VCVARS_2008%" x86 %LIB_NAME%_vs08.sln \vs2008
+if not "x%VCVARS_2008%" == "x" call :BuildLibs "%VCVARS_2008%" x64 %LIB_NAME%_vs08.sln \vs2008
+if not "x%VCVARS_2019%" == "x" call :BuildLibs "%VCVARS_2019%" x86 %LIB_NAME%_vs19.sln
+if not "x%VCVARS_2019%" == "x" call :BuildLibs "%VCVARS_2019%" x64 %LIB_NAME%_vs19.sln
goto:eof
::-----------------------------------------------------------------------------
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
index 4b2bd6d..77590d6 100644
--- a/src/SBaseCommon.cpp
+++ b/src/SBaseCommon.cpp
@@ -23,8 +23,7 @@ char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Lad
DWORD g_dwMpqSignature = ID_MPQ; // Marker for MPQ header
DWORD g_dwHashTableKey = MPQ_KEY_HASH_TABLE; // Key for hash table
DWORD g_dwBlockTableKey = MPQ_KEY_BLOCK_TABLE; // Key for block table
-LCID g_lcFileLocale = LANG_NEUTRAL; // File locale
-USHORT wPlatform = 0; // File platform
+LCID g_lcFileLocale = 0; // Compound of file locale and platform
//-----------------------------------------------------------------------------
// Conversion to uppercase/lowercase
@@ -737,12 +736,13 @@ TMPQFile * IsValidFileHandle(HANDLE hFile)
// Hash table and block table manipulation
// Attempts to search a free hash entry, or an entry whose names and locale matches
-TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale)
+TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcFileLocale)
{
TMPQHash * pDeletedEntry = NULL; // If a deleted entry was found in the continuous hash range
TMPQHash * pFreeEntry = NULL; // If a free entry was found in the continuous hash range
DWORD dwHashIndexMask = HASH_INDEX_MASK(ha);
DWORD dwIndex;
+ USHORT Locale = SFILE_LOCALE(lcFileLocale);
// Set the initial index
dwStartIndex = dwIndex = (dwStartIndex & dwHashIndexMask);
@@ -757,7 +757,7 @@ TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1
TMPQHash * pHash = ha->pHashTable + dwIndex;
// If we found a matching entry, return that one
- if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->lcLocale == lcLocale)
+ if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->Locale == Locale)
return pHash;
// If we found a deleted entry, remember it but keep searching
@@ -849,7 +849,7 @@ TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash *
TMPQHash * AllocateHashEntry(
TMPQArchive * ha,
TFileEntry * pFileEntry,
- LCID lcLocale)
+ LCID lcFileLocale)
{
TMPQHash * pHash;
DWORD dwStartIndex = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_TABLE_INDEX);
@@ -857,14 +857,15 @@ TMPQHash * AllocateHashEntry(
DWORD dwName2 = ha->pfnHashString(pFileEntry->szFileName, MPQ_HASH_NAME_B);
// Attempt to find a free hash entry
- pHash = FindFreeHashEntry(ha, dwStartIndex, dwName1, dwName2, lcLocale);
+ pHash = FindFreeHashEntry(ha, dwStartIndex, dwName1, dwName2, lcFileLocale);
if(pHash != NULL)
{
// Fill the free hash entry
pHash->dwName1 = dwName1;
pHash->dwName2 = dwName2;
- pHash->lcLocale = (USHORT)lcLocale;
- pHash->Platform = 0;
+ pHash->Locale = SFILE_LOCALE(lcFileLocale);
+ pHash->Platform = SFILE_PLATFORM(lcFileLocale);
+ pHash->Reserved = 0;
pHash->dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);
}
diff --git a/src/SBaseDumpData.cpp b/src/SBaseDumpData.cpp
index b08796a..16313dd 100644
--- a/src/SBaseDumpData.cpp
+++ b/src/SBaseDumpData.cpp
@@ -54,7 +54,7 @@ void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize)
printf("[%08x] %08X %08X %04X %02X %08X\n", i,
pHashTable[i].dwName1,
pHashTable[i].dwName2,
- pHashTable[i].lcLocale,
+ pHashTable[i].Locale,
pHashTable[i].Platform,
pHashTable[i].dwBlockIndex);
}
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index 1122ab1..b68de51 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -765,11 +765,13 @@ static bool IsValidHashEntry1(TMPQArchive * ha, TMPQHash * pHash, TMPQBlock * pB
// 2) A hash table entry with the neutral|matching locale and neutral|matching platform
// 3) NULL
// Storm_2016.dll: 15020940
-static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale, BYTE Platform)
+static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale)
{
TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
TMPQHash * pBestEntry = NULL;
TMPQHash * pHash = pFirstHash;
+ USHORT Locale = SFILE_LOCALE(lcFileLocale);
+ BYTE Platform = SFILE_PLATFORM(lcFileLocale);
// Parse the found hashes
while(pHash != NULL)
@@ -778,13 +780,13 @@ static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName,
// If the hash entry matches both locale and platform, return it immediately
// Only do that for non-0 locale&platform, because for loc&plat=0, there's different
// processing in Warcraft III vs. Starcraft, which is abused by some protectors.
- if((lcLocale || Platform) && pHash->lcLocale == lcLocale && pHash->Platform == Platform)
+ if((Locale || Platform) && pHash->Locale == Locale && pHash->Platform == Platform)
return pHash;
// Storm_2016.dll: 150209D9
// If (locale matches or is neutral) AND (platform matches or is neutral), remember this as the best entry
// Also remember the first matching entry for Starcraft maps
- if(pHash->lcLocale == 0 || pHash->lcLocale == lcLocale)
+ if(pHash->Locale == 0 || pHash->Locale == Locale)
{
if(pHash->Platform == 0 || pHash->Platform == Platform)
{
@@ -801,26 +803,31 @@ static TMPQHash * GetHashEntryLocale(TMPQArchive * ha, const char * szFileName,
}
// Returns a hash table entry in the following order:
-// 1) A hash table entry with the preferred locale
+// 1) A hash table entry with the preferred locale&platform
// 2) NULL
-static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+// In case there are multiple items with the same locale&platform,
+// we need to return the last one. This is because it must correspond to SFileOpenFileEx
+static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale)
{
TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
+ TMPQHash * pBestHash = NULL;
TMPQHash * pHash = pFirstHash;
+ USHORT Locale = SFILE_LOCALE(lcFileLocale);
+ BYTE Platform = SFILE_PLATFORM(lcFileLocale);
// Parse the found hashes
while(pHash != NULL)
{
- // If the locales match, return it
- if(pHash->lcLocale == lcLocale)
- return pHash;
+ // If the locales match, we remember this one as the best one
+ if(pHash->Locale == Locale && pHash->Platform == Platform)
+ pBestHash = pHash;
// Get the next hash entry for that file
pHash = GetNextHashEntry(ha, pFirstHash, pHash);
}
- // Not found
- return NULL;
+ // Return the best hash or NULL
+ return pBestHash;
}
// Defragment the file table so it does not contain any gaps
@@ -925,7 +932,6 @@ static DWORD BuildFileTableFromBlockTable(
if(ha->dwFlags & (MPQ_FLAG_HASH_TABLE_CUT | MPQ_FLAG_BLOCK_TABLE_CUT))
{
// Sanity checks
- assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1);
assert(pHeader->HiBlockTablePos64 == 0);
// Allocate the translation table
@@ -1967,7 +1973,7 @@ void FreeBetTable(TMPQBetTable * pBetTable)
//-----------------------------------------------------------------------------
// Support for file table
-TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex)
+TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale, LPDWORD PtrHashIndex)
{
TMPQHash * pHash;
DWORD dwFileIndex;
@@ -1977,7 +1983,7 @@ TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID
// we will need the pointer to hash table entry
if(ha->pHashTable != NULL)
{
- pHash = GetHashEntryLocale(ha, szFileName, lcLocale, 0);
+ pHash = GetHashEntryLocale(ha, szFileName, lcFileLocale);
if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
{
if(PtrHashIndex != NULL)
@@ -1998,7 +2004,7 @@ TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID
return NULL;
}
-TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex)
+TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale, LPDWORD PtrHashIndex)
{
TMPQHash * pHash;
DWORD dwFileIndex;
@@ -2006,7 +2012,7 @@ TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID l
// If the hash table is present, find the entry from hash table
if(ha->pHashTable != NULL)
{
- pHash = GetHashEntryExact(ha, szFileName, lcLocale);
+ pHash = GetHashEntryExact(ha, szFileName, lcFileLocale);
if(pHash != NULL && MPQ_BLOCK_INDEX(pHash) < ha->dwFileTableSize)
{
if(PtrHashIndex != NULL)
@@ -2062,7 +2068,7 @@ void AllocateFileName(TMPQArchive * ha, TFileEntry * pFileEntry, const char * sz
}
}
-TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex)
+TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale, LPDWORD PtrHashIndex)
{
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
TFileEntry * pFreeEntry = NULL;
@@ -2109,10 +2115,10 @@ TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID l
if(ha->pHashTable != NULL)
{
// Make sure that the entry is not there yet
- assert(GetHashEntryExact(ha, szFileName, lcLocale) == NULL);
+ assert(GetHashEntryExact(ha, szFileName, lcFileLocale) == NULL);
// Find a free hash table entry for the name
- pHash = AllocateHashEntry(ha, pFreeEntry, lcLocale);
+ pHash = AllocateHashEntry(ha, pFreeEntry, lcFileLocale);
if(pHash == NULL)
return NULL;
@@ -2139,7 +2145,7 @@ DWORD RenameFileEntry(
{
TFileEntry * pFileEntry = hf->pFileEntry;
TMPQHash * pHashEntry = hf->pHashEntry;
- LCID lcLocale = 0;
+ LCID lcFileLocale = 0;
// If the archive hash hash table, we need to free the hash table entry
if(ha->pHashTable != NULL)
@@ -2150,12 +2156,12 @@ DWORD RenameFileEntry(
return ERROR_NOT_SUPPORTED;
// Save the locale
- lcLocale = pHashEntry->lcLocale;
+ lcFileLocale = SFILE_MAKE_LCID(pHashEntry->Locale, pHashEntry->Platform);
// Mark the hash table entry as deleted
pHashEntry->dwName1 = 0xFFFFFFFF;
pHashEntry->dwName2 = 0xFFFFFFFF;
- pHashEntry->lcLocale = 0xFFFF;
+ pHashEntry->Locale = 0xFFFF;
pHashEntry->Platform = 0xFF;
pHashEntry->Reserved = 0xFF;
pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED;
@@ -2173,7 +2179,7 @@ DWORD RenameFileEntry(
if(ha->pHashTable != NULL)
{
// Since we freed one hash entry before, this must succeed
- hf->pHashEntry = AllocateHashEntry(ha, pFileEntry, lcLocale);
+ hf->pHashEntry = AllocateHashEntry(ha, pFileEntry, lcFileLocale);
assert(hf->pHashEntry != NULL);
}
@@ -2196,7 +2202,7 @@ DWORD DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf)
// Mark the hash table entry as deleted
pHashEntry->dwName1 = 0xFFFFFFFF;
pHashEntry->dwName2 = 0xFFFFFFFF;
- pHashEntry->lcLocale = 0xFFFF;
+ pHashEntry->Locale = 0xFFFF;
pHashEntry->Platform = 0xFF;
pHashEntry->Reserved = 0xFF;
pHashEntry->dwBlockIndex = HASH_ENTRY_DELETED;
@@ -2928,7 +2934,7 @@ DWORD RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize)
if(IsValidHashEntry(ha, pHash))
{
pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash);
- AllocateHashEntry(ha, pFileEntry, pHash->lcLocale);
+ AllocateHashEntry(ha, pFileEntry, SFILE_MAKE_LCID(pHash->Locale, pHash->Platform));
}
}
diff --git a/src/SBaseSubTypes.cpp b/src/SBaseSubTypes.cpp
index 9808ef3..59be7e8 100644
--- a/src/SBaseSubTypes.cpp
+++ b/src/SBaseSubTypes.cpp
@@ -53,7 +53,7 @@ typedef struct _TSQPHeader
typedef struct _TSQPHash
{
- // Most likely the lcLocale+wPlatform.
+ // Most likely the Locale + Platform
DWORD dwAlwaysZero;
// If the hash table entry is valid, this is the index into the block table of the file.
@@ -216,8 +216,8 @@ TMPQHash * LoadSqpHashTable(TMPQArchive * ha)
pMpqHash->dwName1 = TempEntry.dwName1;
pMpqHash->dwName2 = TempEntry.dwName2;
pMpqHash->dwBlockIndex = MPQ_BLOCK_INDEX(&TempEntry);
+ pMpqHash->Locale = 0;
pMpqHash->Platform = 0;
- pMpqHash->lcLocale = 0;
pMpqHash->Reserved = 0;
}
}
@@ -547,8 +547,9 @@ TMPQHash * LoadMpkHashTable(TMPQArchive * ha)
// Copy the MPK hash entry to the hash table
pHash->dwBlockIndex = pMpkHash[i].dwBlockIndex;
+ pHash->Locale = 0;
pHash->Platform = 0;
- pHash->lcLocale = 0;
+ pHash->Reserved = 0;
pHash->dwName1 = pMpkHash[i].dwName2;
pHash->dwName2 = pMpkHash[i].dwName3;
}
diff --git a/src/SFileAddFile.cpp b/src/SFileAddFile.cpp
index a65244e..b1288f1 100644
--- a/src/SFileAddFile.cpp
+++ b/src/SFileAddFile.cpp
@@ -400,7 +400,7 @@ DWORD SFileAddFile_Init(
const char * szFileName,
ULONGLONG FileTime,
DWORD dwFileSize,
- LCID lcLocale,
+ LCID lcFileLocale,
DWORD dwFlags,
TMPQFile ** phf)
{
@@ -430,7 +430,7 @@ DWORD SFileAddFile_Init(
// If the MPQ is of version 3.0 or higher, we ignore file locale.
// This is because HET and BET tables have no known support for it
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_3)
- lcLocale = 0;
+ lcFileLocale = 0;
// Allocate the TMPQFile entry for newly added file
hf = CreateWritableHandle(ha, dwFileSize);
@@ -441,7 +441,7 @@ DWORD SFileAddFile_Init(
if(dwErrCode == ERROR_SUCCESS)
{
// Check if the file already exists in the archive
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcLocale, &dwHashIndex);
+ pFileEntry = GetFileEntryExact(ha, szFileName, lcFileLocale, &dwHashIndex);
if(pFileEntry != NULL)
{
if(dwFlags & MPQ_FILE_REPLACEEXISTING)
@@ -452,7 +452,7 @@ DWORD SFileAddFile_Init(
else
{
// Attempt to allocate new file entry
- pFileEntry = AllocateFileEntry(ha, szFileName, lcLocale, &dwHashIndex);
+ pFileEntry = AllocateFileEntry(ha, szFileName, lcFileLocale, &dwHashIndex);
if(pFileEntry != NULL)
InvalidateInternalFiles(ha);
else
@@ -467,7 +467,9 @@ DWORD SFileAddFile_Init(
if(dwErrCode == ERROR_SUCCESS && ha->pHashTable != NULL && dwHashIndex < ha->pHeader->dwHashTableSize)
{
hf->pHashEntry = ha->pHashTable + dwHashIndex;
- hf->pHashEntry->lcLocale = (USHORT)lcLocale;
+ hf->pHashEntry->Locale = SFILE_LOCALE(lcFileLocale);
+ hf->pHashEntry->Platform = SFILE_PLATFORM(lcFileLocale);
+ hf->pHashEntry->Reserved = 0;
}
// Prepare the file key
@@ -762,7 +764,7 @@ bool WINAPI SFileCreateFile(
const char * szArchivedName,
ULONGLONG FileTime,
DWORD dwFileSize,
- LCID lcLocale,
+ LCID lcFileLocale,
DWORD dwFlags,
HANDLE * phFile)
{
@@ -805,7 +807,7 @@ bool WINAPI SFileCreateFile(
// Initiate the add file operation
if(dwErrCode == ERROR_SUCCESS)
- dwErrCode = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile);
+ dwErrCode = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcFileLocale, dwFlags, (TMPQFile **)phFile);
// Deal with the errors
if(dwErrCode != ERROR_SUCCESS)
@@ -1293,7 +1295,9 @@ bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale)
}
// Update the locale in the hash table entry
- hf->pHashEntry->lcLocale = (USHORT)lcNewLocale;
+ hf->pHashEntry->Locale = SFILE_LOCALE(lcNewLocale);
+ hf->pHashEntry->Platform = SFILE_PLATFORM(lcNewLocale);
+ hf->pHashEntry->Reserved = 0;
ha->dwFlags |= MPQ_FLAG_CHANGED;
return true;
}
diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp
index 223e194..4de1022 100644
--- a/src/SFileFindFile.cpp
+++ b/src/SFileFindFile.cpp
@@ -263,7 +263,7 @@ static bool DoMPQSearch_FileEntry(
lpFindFileData->dwFileSize = pPatchEntry->dwFileSize;
lpFindFileData->dwFileFlags = pPatchEntry->dwFlags;
lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize;
- lpFindFileData->lcLocale = 0; // pPatchEntry->lcLocale;
+ lpFindFileData->lcLocale = 0; // pPatchEntry->lcFileLocale;
// Fill the filetime
lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
@@ -273,7 +273,7 @@ static bool DoMPQSearch_FileEntry(
if(pHashEntry != NULL)
{
lpFindFileData->dwHashIndex = (DWORD)(pHashEntry - ha->pHashTable);
- lpFindFileData->lcLocale = pHashEntry->lcLocale;
+ lpFindFileData->lcLocale = SFILE_MAKE_LCID(pHashEntry->Locale, pHashEntry->Platform);
}
// Fill the file name and plain file name
diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp
index b980755..77c86fd 100644
--- a/src/SFileGetFileInfo.cpp
+++ b/src/SFileGetFileInfo.cpp
@@ -410,7 +410,7 @@ bool WINAPI SFileGetFileInfo(
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileInfoLocale:
- dwInt32Value = hf->pHashEntry->lcLocale;
+ dwInt32Value = SFILE_MAKE_LCID(hf->pHashEntry->Locale, hf->pHashEntry->Platform);
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoFileIndex:
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp
index 8ce9ae4..6adf1ab 100644
--- a/src/SFileListFile.cpp
+++ b/src/SFileListFile.cpp
@@ -580,7 +580,7 @@ static DWORD SFileAddInternalListFile(
while(dwErrCode == ERROR_SUCCESS && pHash != NULL)
{
// Set the prefered locale to that from list file
- SFileSetLocale(pHash->lcLocale);
+ SFileSetLocale(SFILE_MAKE_LCID(pHash->Locale, pHash->Platform));
// Add that listfile
dwErrCode = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize);
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp
index b85f24c..16e2491 100644
--- a/src/SFileOpenArchive.cpp
+++ b/src/SFileOpenArchive.cpp
@@ -209,10 +209,9 @@ LCID WINAPI SFileGetLocale()
return g_lcFileLocale;
}
-LCID WINAPI SFileSetLocale(LCID lcNewLocale)
+LCID WINAPI SFileSetLocale(LCID lcFileLocale)
{
- g_lcFileLocale = lcNewLocale;
- return g_lcFileLocale;
+ return (g_lcFileLocale = lcFileLocale);
}
//-----------------------------------------------------------------------------
diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp
index 96d8cfc..5dc2dbf 100644
--- a/src/SFileOpenFileEx.cpp
+++ b/src/SFileOpenFileEx.cpp
@@ -170,13 +170,13 @@ bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile)
//-----------------------------------------------------------------------------
// SFileEnumLocales enums all locale versions within MPQ.
// Functions fills all available language identifiers on a file into the buffer
-// pointed by plcLocales. There must be enough entries to copy the localed,
+// pointed by PtrFileLocales. There must be enough entries to copy the localed,
// otherwise the function returns ERROR_INSUFFICIENT_BUFFER.
DWORD WINAPI SFileEnumLocales(
HANDLE hMpq,
const char * szFileName,
- LCID * PtrLocales,
+ LCID * PtrFileLocales,
LPDWORD PtrMaxLocales,
DWORD dwSearchScope)
{
@@ -208,8 +208,8 @@ DWORD WINAPI SFileEnumLocales(
while(pHash != NULL)
{
// Put the locales to the buffer
- if(PtrLocales != NULL && dwLocales < dwMaxLocales)
- *PtrLocales++ = pHash->lcLocale;
+ if(PtrFileLocales != NULL && dwLocales < dwMaxLocales)
+ *PtrFileLocales++ = SFILE_MAKE_LCID(pHash->Locale, pHash->Platform);
dwLocales++;
// Get the next locale
diff --git a/src/StormCommon.h b/src/StormCommon.h
index 7ff55e8..48fd86f 100644
--- a/src/StormCommon.h
+++ b/src/StormCommon.h
@@ -141,7 +141,7 @@ typedef struct _MPQ_SIGNATURE_INFO
extern DWORD g_dwMpqSignature; // Marker for MPQ header
extern DWORD g_dwHashTableKey; // Key for hash table
extern DWORD g_dwBlockTableKey; // Key for block table
-extern LCID g_lcFileLocale; // Preferred file locale
+extern LCID g_lcFileLocale; // Preferred file locale and platform
//-----------------------------------------------------------------------------
// Conversion to uppercase/lowercase (and "/" to "\")
@@ -250,10 +250,10 @@ DWORD ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG
bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash);
-TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale);
+TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcFileLocale);
TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName);
TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash);
-TMPQHash * AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry, LCID lcLocale);
+TMPQHash * AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry, LCID lcFileLocale);
TMPQExtHeader * LoadExtTable(TMPQArchive * ha, ULONGLONG ByteOffset, size_t Size, DWORD dwSignature, DWORD dwKey);
TMPQHetTable * LoadHetTable(TMPQArchive * ha);
@@ -282,14 +282,14 @@ TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount);
void FreeBetTable(TMPQBetTable * pBetTable);
// Functions for finding files in the file table
-TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex = NULL);
-TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex);
+TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale, LPDWORD PtrHashIndex = NULL);
+TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale, LPDWORD PtrHashIndex);
// Allocates file name in the file entry
void AllocateFileName(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szFileName);
// Allocates new file entry in the MPQ tables. Reuses existing, if possible
-TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex);
+TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale, LPDWORD PtrHashIndex);
DWORD RenameFileEntry(TMPQArchive * ha, TMPQFile * hf, const char * szNewFileName);
DWORD DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf);
@@ -378,7 +378,7 @@ DWORD SFileAddFile_Init(
const char * szArchivedName,
ULONGLONG ft,
DWORD dwFileSize,
- LCID lcLocale,
+ LCID lcFileLocale,
DWORD dwFlags,
TMPQFile ** phf
);
diff --git a/src/StormLib.h b/src/StormLib.h
index 1c4e199..85f5c4b 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -73,6 +73,7 @@
/* 18.09.15 9.20 Lad Release 9.20 */
/* 12.12.16 9.21 Lad Release 9.21 */
/* 10.11.17 9.22 Lad Release 9.22 */
+/* 28.09.22 9.24 Lad lcLocale -> lcFileLocale, also contains platform */
/*****************************************************************************/
#ifndef __STORMLIB_H__
@@ -142,8 +143,8 @@ extern "C" {
//-----------------------------------------------------------------------------
// Defines
-#define STORMLIB_VERSION 0x0917 // Current version of StormLib (9.23)
-#define STORMLIB_VERSION_STRING "9.23" // String version of StormLib version
+#define STORMLIB_VERSION 0x0918 // Current version of StormLib (9.24)
+#define STORMLIB_VERSION_STRING "9.24" // String version of StormLib version
#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A')
#define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B')
@@ -627,7 +628,7 @@ typedef struct _TMPQHash
// The language of the file. This is a Windows LANGID data type, and uses the same values.
// 0 indicates the default language (American English), or that the file is language-neutral.
- USHORT lcLocale;
+ USHORT Locale;
// The platform the file is used for. 0 indicates the default platform.
// No other values have been observed.
@@ -638,7 +639,7 @@ typedef struct _TMPQHash
BYTE Reserved;
BYTE Platform;
- USHORT lcLocale;
+ USHORT Locale;
#endif
@@ -910,7 +911,7 @@ typedef struct _SFILE_FIND_DATA
DWORD dwCompSize; // Compressed file size
DWORD dwFileTimeLo; // Low 32-bits of the file time (0 if not present)
DWORD dwFileTimeHi; // High 32-bits of the file time (0 if not present)
- LCID lcLocale; // Locale version
+ LCID lcLocale; // Compound of file locale (16 bits) and platform (8 bits)
} SFILE_FIND_DATA, *PSFILE_FIND_DATA;
@@ -994,13 +995,18 @@ typedef bool (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAP
//-----------------------------------------------------------------------------
// Functions for manipulation with StormLib global flags
+// Macros for making LCID from Locale and Platform
+#define SFILE_MAKE_LCID(locale, platform) ((LCID)(USHORT)locale | (LCID)(BYTE)platform << 0x10)
+#define SFILE_LOCALE(lcFileLocale) (USHORT)(lcFileLocale & 0xFFFF)
+#define SFILE_PLATFORM(lcFileLocale) (BYTE)(lcFileLocale >> 0x10)
+
// Alternate marker support. This is for MPQs masked as DLLs (*.asi), which
// patch Storm.dll at runtime. Call before SFileOpenArchive
bool WINAPI SFileSetArchiveMarkers(PSFILE_MARKERS pMarkers);
// Call before SFileOpenFileEx
LCID WINAPI SFileGetLocale();
-LCID WINAPI SFileSetLocale(LCID lcNewLocale);
+LCID WINAPI SFileSetLocale(LCID lcFileLocale);
//-----------------------------------------------------------------------------
// Functions for archive manipulation
@@ -1085,12 +1091,12 @@ bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileDa
bool WINAPI SListFileFindClose(HANDLE hFind);
// Locale support
-DWORD WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope);
+DWORD WINAPI SFileEnumLocales(HANDLE hMpq, const char * szFileName, LCID * PtrFileLocales, LPDWORD PtrMaxLocales, DWORD dwSearchScope);
//-----------------------------------------------------------------------------
// Support for adding files to the MPQ
-bool WINAPI SFileCreateFile(HANDLE hMpq, const char * szArchivedName, ULONGLONG FileTime, DWORD dwFileSize, LCID lcLocale, DWORD dwFlags, HANDLE * phFile);
+bool WINAPI SFileCreateFile(HANDLE hMpq, const char * szArchivedName, ULONGLONG FileTime, DWORD dwFileSize, LCID lcFileLocale, DWORD dwFlags, HANDLE * phFile);
bool WINAPI SFileWriteFile(HANDLE hFile, const void * pvData, DWORD dwSize, DWORD dwCompression);
bool WINAPI SFileFinishFile(HANDLE hFile);
diff --git a/test/StormTest.cpp b/test/StormTest.cpp
index c4b3179..e7a2434 100644
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -41,6 +41,10 @@
#define TFLG_VALUE_MASK 0x00FFFFFF // Mask for integer value
#define TEST_DATA(hash, num) (num | TFLG_COUNT_HASH), hash
+#define ERROR_UNDETERMINED_RESULT 0xC000FFFF
+
+typedef DWORD(*FIND_FILE_CALLBACK)(LPCTSTR szFullPath);
+
typedef struct _TEST_INFO
{
LPCTSTR szMpqName1;
@@ -85,11 +89,6 @@ 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);
-
-#define ERROR_UNDETERMINED_RESULT 0xC000FFFF
-
//-----------------------------------------------------------------------------
// Testing data
@@ -156,6 +155,12 @@ static const wchar_t szUnicodeName6[] = { // Arabic
0x0627, 0x0644, 0x0639, 0x0639, 0x0631, 0x0628, 0x064A, 0x0629, _T('.'), _T('m'), _T('p'), _T('q'), 0
};
+static SFILE_MARKERS MpqMarkers[] =
+{
+ {sizeof(SFILE_MARKERS), ID_MPQ, "(hash table)", "(block table)"},
+ {sizeof(SFILE_MARKERS), 'XHSC', "(cash table)", "(clock table)"}
+};
+
static LPCTSTR PatchList_StarCraft[] =
{
_T("MPQ_1998_v1_StarCraft.mpq"),
@@ -1386,14 +1391,14 @@ static TFileData * LoadLocalFile(TLogHelper * pLogger, LPCTSTR szFileName, bool
return pFileData;
}
-static DWORD LoadLocalFileMD5(TLogHelper * pLogger, LPCTSTR szLocalFileName, LPBYTE md5_file_local)
+static DWORD LoadLocalFileMD5(TLogHelper * pLogger, LPCTSTR szFileFullName, LPBYTE md5_file_local)
{
TFileData * pFileData;
// Load the local file to memory
- if((pFileData = LoadLocalFile(pLogger, szLocalFileName, true)) == NULL)
+ if((pFileData = LoadLocalFile(pLogger, szFileFullName, true)) == NULL)
{
- return pLogger->PrintError(_T("The file \"%s\" could not be loaded"), szLocalFileName);
+ return pLogger->PrintError(_T("The file \"%s\" could not be loaded"), szFileFullName);
}
// Calculate the hash
@@ -1402,7 +1407,7 @@ static DWORD LoadLocalFileMD5(TLogHelper * pLogger, LPCTSTR szLocalFileName, LPB
return ERROR_SUCCESS;
}
-static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, LCID lcLocale = 0, bool bIgnoreOpedwErrCodes = false)
+static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, LCID lcFileLocale = 0, bool bIgnoreOpedwErrCodes = false)
{
TFileData * pFileData = NULL;
HANDLE hFile;
@@ -1421,7 +1426,7 @@ static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileN
#endif
// Make sure that we open the proper locale file
- SFileSetLocale(lcLocale);
+ SFileSetLocale(lcFileLocale);
// Open the file from MPQ
if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile))
@@ -1817,7 +1822,7 @@ static DWORD CreateNewArchiveU(TLogHelper * pLogger, const wchar_t * szPlainName
static DWORD OpenExistingArchive(TLogHelper * pLogger, LPCTSTR szFullPath, DWORD dwFlags, HANDLE * phMpq)
{
HANDLE hMpq = NULL;
-// bool bReopenResult;
+ size_t nMarkerIndex;
DWORD dwErrCode = ERROR_SUCCESS;
// Is it an encrypted MPQ ?
@@ -1830,6 +1835,10 @@ static DWORD OpenExistingArchive(TLogHelper * pLogger, LPCTSTR szFullPath, DWORD
if(_tcsstr(szFullPath, _T(".MPQ.0")) != NULL)
dwFlags |= STREAM_PROVIDER_BLOCK4;
+ // Handle ASI files properly
+ nMarkerIndex = (_tcsstr(szFullPath, _T(".asi")) != NULL) ? 1 : 0;
+ SFileSetArchiveMarkers(&MpqMarkers[nMarkerIndex]);
+
// Open the copied archive
pLogger->PrintProgress(_T("Opening archive %s ..."), GetShortPlainName(szFullPath));
if(!SFileOpenArchive(szFullPath, 0, dwFlags, &hMpq))
@@ -1991,7 +2000,7 @@ static DWORD AddLocalFileToMpq(
TLogHelper * pLogger,
HANDLE hMpq,
LPCSTR szArchivedName,
- LPCTSTR szLocalFileName,
+ LPCTSTR szFileFullName,
DWORD dwFlags = 0,
DWORD dwCompression = 0,
bool bMustSucceed = false)
@@ -2000,7 +2009,7 @@ static DWORD AddLocalFileToMpq(
DWORD dwVerifyResult;
// Notify the user
- pLogger->PrintProgress("Adding file %s (%u of %u)...", GetShortPlainName(szLocalFileName), pLogger->UserCount, pLogger->UserTotal);
+ pLogger->PrintProgress("Adding file %s (%u of %u)...", GetShortPlainName(szFileFullName), pLogger->UserCount, pLogger->UserTotal);
pLogger->UserString = szArchivedName;
// Get the default flags
@@ -2013,7 +2022,7 @@ static DWORD AddLocalFileToMpq(
SFileSetAddFileCallback(hMpq, AddFileCallback, pLogger);
// Add the file to the MPQ
- StringCopy(szFileName, _countof(szFileName), szLocalFileName);
+ StringCopy(szFileName, _countof(szFileName), szFileFullName);
if(!SFileAddFileEx(hMpq, szFileName, szArchivedName, dwFlags, dwCompression, MPQ_COMPRESSION_NEXT_SAME))
{
if(bMustSucceed)
@@ -2507,7 +2516,7 @@ static DWORD TestArchive(
DWORD dwExpectedFileCount = 0;
DWORD dwMpqFlags = 0;
TCHAR szFullName[MAX_PATH];
- LCID lcLocale = 0;
+ LCID lcFileLocale = 0;
BYTE ObtainedMD5[MD5_DIGEST_SIZE] = {0};
bool bIgnoreOpedwErrCodes = false;
@@ -2527,7 +2536,7 @@ static DWORD TestArchive(
// If locale entered
if(dwFlags & TFLG_FILE_LOCALE)
{
- lcLocale = (LCID)(dwFlags & TFLG_VALUE_MASK);
+ lcFileLocale = (LCID)(dwFlags & TFLG_VALUE_MASK);
}
// Put all file names into list
@@ -2574,7 +2583,7 @@ static DWORD TestArchive(
break;
// Load the entire file 1
- FileDataList[i] = pFileData = LoadMpqFile(&Logger, hMpq, szFileName, lcLocale);
+ FileDataList[i] = pFileData = LoadMpqFile(&Logger, hMpq, szFileName, lcFileLocale);
if(pFileData == NULL)
{
dwErrCode = Logger.PrintError("Failed to load the file %s", szFileName);
@@ -3838,7 +3847,7 @@ static DWORD TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
TCHAR szFileName2[MAX_PATH];
TCHAR szFullPath[MAX_PATH];
LPCSTR szMiddleFile = "FileTest_10.exe";
- LCID LocaleIDs[] = {0x000, 0x405, 0x406, 0x407, 0xFFFF};
+ LCID LocaleIDs[] = {0x000, 0x405, 0x406, 0x407};
char szArchivedName[MAX_PATH];
DWORD dwMaxFileCount = 0;
DWORD dwFileCount = 0;
@@ -3896,7 +3905,7 @@ static DWORD TestCreateArchive_FileFlagTest(LPCTSTR szPlainName)
// Add ZeroSize.txt several times under a different locale
if(dwErrCode == ERROR_SUCCESS)
{
- for(size_t i = 0; LocaleIDs[i] != 0xFFFF; i++)
+ for(size_t i = 0; i < _countof(LocaleIDs); i++)
{
bool bMustSucceed = ((dwFileCount + 2) < dwMaxFileCount);
@@ -4194,11 +4203,12 @@ static DWORD TestCreateArchive_BigArchive(LPCTSTR szPlainName)
}
// "MPQ_2014_v4_Heroes_Replay.MPQ", "AddFile-replay.message.events"
-static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFileName)
+static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFilePlainName)
{
TLogHelper Logger("ModifyTest", szMpqPlainName);
HANDLE hMpq = NULL;
- TCHAR szLocalFileName[MAX_PATH];
+ TCHAR szFileFullName[MAX_PATH];
+ TCHAR szMpqFullName[MAX_PATH];
char szArchivedName[MAX_PATH];
size_t nOffset = 0;
DWORD dwErrCode;
@@ -4207,11 +4217,14 @@ static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFil
BYTE md5_file_in_mpq3[MD5_DIGEST_SIZE];
BYTE md5_file_local[MD5_DIGEST_SIZE];
- // Get the name of archived file
- if(!_tcsnicmp(szFileName, _T("AddFile-"), 8))
+ // Get the name of archived file as plain text
+ if(!_tcsnicmp(szFilePlainName, _T("AddFile-"), 8))
nOffset = 8;
- StringCopy(szArchivedName, _countof(szArchivedName), szFileName + nOffset);
- CreateFullPathName(szLocalFileName, _countof(szLocalFileName), szMpqSubDir, szFileName);
+ StringCopy(szArchivedName, _countof(szArchivedName), szFilePlainName + nOffset);
+
+ // Get the full path of the archive and local file
+ CreateFullPathName(szFileFullName, _countof(szFileFullName), szMpqSubDir, szFilePlainName);
+ CreateFullPathName(szMpqFullName, _countof(szMpqFullName), NULL, szMpqPlainName);
// Open an existing archive
dwErrCode = OpenExistingArchiveWithCopy(&Logger, szMpqPlainName, szMpqPlainName, &hMpq);
@@ -4225,7 +4238,7 @@ static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFil
// Open the local file, calculate hash
if(dwErrCode == ERROR_SUCCESS)
{
- dwErrCode = LoadLocalFileMD5(&Logger, szLocalFileName, md5_file_local);
+ dwErrCode = LoadLocalFileMD5(&Logger, szFileFullName, md5_file_local);
}
// Add the given file
@@ -4234,7 +4247,7 @@ static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFil
// Add the file to MPQ
dwErrCode = AddLocalFileToMpq(&Logger, hMpq,
szArchivedName,
- szLocalFileName,
+ szFileFullName,
MPQ_FILE_REPLACEEXISTING | MPQ_FILE_COMPRESS | MPQ_FILE_SINGLE_UNIT,
MPQ_COMPRESSION_ZLIB,
true);
@@ -4271,16 +4284,16 @@ static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFil
if(!SFileSetCompactCallback(hMpq, CompactCallback, &Logger))
dwErrCode = Logger.PrintError(_T("Failed to compact archive %s"), szMpqPlainName);
- if(!SFileCompactArchive(hMpq, NULL, 0))
- dwErrCode = GetLastError();
-
+ // Some test archives (like MPQ_2022_v1_v4.329.w3x) can't be compacted.
+ // For that reason, we ignore the result of SFileCompactArchive().
+ SFileCompactArchive(hMpq, NULL, 0);
SFileCloseArchive(hMpq);
}
// Try to open the archive again. Ignore the previous errors
if(dwErrCode == ERROR_SUCCESS)
{
- dwErrCode = OpenExistingArchive(&Logger, szLocalFileName, 0, &hMpq);
+ dwErrCode = OpenExistingArchive(&Logger, szMpqFullName, 0, &hMpq);
if(dwErrCode == ERROR_SUCCESS)
{
// Load the file from the MPQ again
@@ -4288,7 +4301,7 @@ static DWORD TestModifyArchive_ReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFil
if(dwErrCode == ERROR_SUCCESS)
{
// New MPQ file must be the same like the local one
- if(!memcmp(md5_file_in_mpq3, md5_file_local, MD5_DIGEST_SIZE))
+ if(memcmp(md5_file_in_mpq3, md5_file_local, MD5_DIGEST_SIZE))
{
Logger.PrintError("Data mismatch after adding the file \"%s\"", szArchivedName);
dwErrCode = ERROR_CHECKSUM_ERROR;
@@ -4386,6 +4399,11 @@ static const TEST_INFO Test_Mpqs[] =
{_T("MPQ_2021_v1_CantExtractCHK.scx"), NULL, TEST_DATA("055fd548a789c910d9dd37472ecc1e66", 28)},
{_T("MPQ_2022_v1_Sniper.scx"), NULL, TEST_DATA("2e955271b70b79344ad85b698f6ce9d8", 64)}, // Multiple items in hash table for staredit\scenario.chk (locale=0, platform=0)
{_T("MPQ_2022_v1_OcOc_Bound_2.scx"), NULL, TEST_DATA("25cad16a2fb4e883767a1f512fc1dce7", 16)},
+
+ // ASI plugins
+ {_T("MPQ_2020_v1_HS0.1.asi"), NULL, TEST_DATA("50cba7460a6e6d270804fb9776a7ec4f", 6022)},
+ {_T("MPQ_2022_v1_hs0.8.asi"), NULL, TEST_DATA("6a40f733428001805bfe6e107ca9aec1", 11352)}, // Items in hash table have platform = 0xFF
+ {_T("MPQ_2022_v1_MoeMoeMod.asi"), NULL, TEST_DATA("89b923c7cde06de48815844a5bbb0ec4", 2578)},
};
static const TEST_INFO Patched_Mpqs[] =
@@ -4476,13 +4494,12 @@ int _tmain(int argc, TCHAR * argv[])
{
for(size_t i = 0; i < _countof(Test_Mpqs); i++)
{
+ // Ignore the error code here; we want to see results of all opens
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;
}
}
@@ -4498,11 +4515,10 @@ int _tmain(int argc, TCHAR * argv[])
LPCTSTR * PatchList = (LPCTSTR *)Patched_Mpqs[i].param1;
LPCSTR szFileName = (LPCSTR)Patched_Mpqs[i].param2;
+ // Ignore the error code here; we want to see results of all opens
dwErrCode = TestArchive_Patched(PatchList, // List of patches
szFileName, // Name of a file
Patched_Mpqs[i].dwFlags);
-// if(dwErrCode != ERROR_SUCCESS)
-// break;
dwErrCode = ERROR_SUCCESS;
}
}
diff --git a/test/stormlib-test.txt b/test/stormlib-test.txt
index 4a1bd2c..947a387 100644
--- a/test/stormlib-test.txt
+++ b/test/stormlib-test.txt
@@ -1,8 +1,8 @@
-Microsoft Windows [Version 10.0.19044.1706]
+Microsoft Windows [Version 10.0.19044.2006]
(c) Microsoft Corporation. All rights reserved.
E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release>StormLib_test.exe
-==== Test Suite for StormLib version 9.23 ====
+==== Test Suite for StormLib version 9.24 ====
InitWorkDir: Work directory \Multimedia\MPQs (default)
LocalListFile (FLAT-MAP:ListFile_Blizzard.txt) succeeded.
LocalListFile (ListFile_Blizzard.txt) succeeded.
@@ -68,6 +68,9 @@ TestMpq (MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x) succeeded.
TestMpq (MPQ_2021_v1_CantExtractCHK.scx) succeeded.
TestMpq (MPQ_2022_v1_Sniper.scx) succeeded.
TestMpq (MPQ_2022_v1_OcOc_Bound_2.scx) succeeded.
+TestMpq (MPQ_2020_v1_HS0.1.asi) succeeded.
+TestMpq (MPQ_2022_v1_hs0.8.asi) succeeded.
+TestMpq (MPQ_2022_v1_MoeMoeMod.asi) succeeded.
PatchedMPQ (MPQ_1998_v1_StarCraft.mpq) succeeded.
PatchedMPQ (MPQ_2012_v4_OldWorld.MPQ) succeeded.
PatchedMPQ (MPQ_2013_v4_world.MPQ) succeeded.
@@ -171,6 +174,8 @@ VerifyFileHash succeeded.
VerifyFileHash succeeded.
VerifyFileHash succeeded.
VerifyFileHash succeeded.
+VerifyFileHash succeeded.
+VerifyFileHash succeeded.
OpenEachMpqTest ((10)DustwallowKeys.w3m) succeeded.
OpenEachMpqTest (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded.
OpenEachMpqTest (MPQ_1997_v1_Diablo1_single_0.sv) succeeded.
@@ -236,7 +241,7 @@ OpenEachMpqTest (MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x) succeeded.
OpenEachMpqTest (MPQ_2017_v1_TildeInFileName.mpq) succeeded.
OpenEachMpqTest (MPQ_2018_v1_EWIX_v8_7.w3x) succeeded.
OpenEachMpqTest (MPQ_2018_v1_icon_error.w3m) succeeded.
-OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\1995 - Test MPQs\MPQ_2020_v1_HS0.1.asi (error code: 11)
+OpenEachMpqTest (MPQ_2020_v1_HS0.1.asi) succeeded.
OpenEachMpqTest (MPQ_2020_v4_FakeMpqHeaders.SC2Mod) succeeded.
OpenEachMpqTest (MPQ_2020_v4_NP_Protect_1.s2ma) succeeded.
OpenEachMpqTest (MPQ_2020_v4_NP_Protect_2.s2ma) succeeded.
@@ -245,7 +250,9 @@ OpenEachMpqTest (MPQ_2020_v4_NP_Protect_4.s2ma) succeeded.
OpenEachMpqTest (MPQ_2020_v4_ThreeFakeHeaders.s2ma) succeeded.
OpenEachMpqTest (MPQ_2021_v1_CrossLinkedFiles.w3x) succeeded.
OpenEachMpqTest (MPQ_2021_v4_BzipError.SC2Replay) succeeded.
-OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\1995 - Test MPQs\MPQ_2022_v1_MoeMoeMod.asi (error code: 11)
+OpenEachMpqTest (MPQ_2022_v1_hs0.8.asi) succeeded.
+OpenEachMpqTest (MPQ_2022_v1_MoeMoeMod.asi) succeeded.
+OpenEachMpqTest (MPQ_2022_v1_v4.329.w3x) succeeded.
OpenEachMpqTest (hs-0-3604-Win-final.MPQ) succeeded.
OpenEachMpqTest (hs-0-5314-Win-final.MPQ) succeeded.
OpenEachMpqTest (hs-5314-5435-Win-final.MPQ) succeeded.
@@ -343,10 +350,10 @@ OpenEachMpqTest ((4)aaaa.w3x) succeeded.
OpenEachMpqTest (a_tvse_x_1_2_f.w3x) succeeded.
OpenEachMpqTest (Shopping_Maul_ USA 9.10.7.w3x) succeeded.
OpenEachMpqTest (siverrpg_1.9_ver.w3x) succeeded.
-OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\2002 - Warcraft III\MIX-files\Markers-CSHX\ACGExternal0.2.asi (error code: 11)
-OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\2002 - Warcraft III\MIX-files\Markers-CSHX\grandparty.asi (error code: 11)
-OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\2002 - Warcraft III\MIX-files\Markers-CSHX\HS0.1.asi (error code: 11)
-OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\2002 - Warcraft III\MIX-files\Markers-CSHX\HS0.5.asi (error code: 11)
+OpenEachMpqTest (ACGExternal0.2.asi) succeeded.
+OpenEachMpqTest (grandparty.asi) succeeded.
+OpenEachMpqTest (HS0.1.asi) succeeded.
+OpenEachMpqTest (HS0.5.asi) succeeded.
OpenEachMpqTest (Patch_War3x.mpq) succeeded.
OpenEachMpqTest (Patch_War3_Low.mpq) succeeded.
OpenEachMpqTest (Patch_War3_Med.mpq) succeeded.
@@ -2277,6 +2284,7 @@ OpenEachMpqTest (MPQ_2013_v4_alternate-incomplete.MPQ) succeeded.
OpenEachMpqTest (MPQ_2013_v4_alternate-original.MPQ) succeeded.
OpenEachMpqTest (MPQ_2014_v1_out1.w3x) succeeded.
OpenEachMpqTest (MPQ_2014_v1_out2.w3x) succeeded.
+OpenEachMpqTest (MPQ_2022_v1_v4.329.w3x) succeeded.
OpenEachMpqTest (StormLibTest_AddWaveMonoBadTest.mpq) succeeded.
OpenEachMpqTest (StormLibTest_AddWaveMonoTest.mpq) succeeded.
OpenEachMpqTest (StormLibTest_AddWaveStereoTest.mpq) succeeded.
@@ -2338,5 +2346,6 @@ CompressionsTest (StormLibTest_AddWaveStereoTest.mpq) succeeded.
ListFilePos (StormLibTest_ListFilePos.mpq) succeeded.
BigMpqTest (StormLibTest_BigArchive_v4.mpq) succeeded.
ModifyTest (MPQ_2014_v4_Base.StormReplay) succeeded.
+ModifyTest (MPQ_2022_v1_v4.329.w3x) succeeded.
E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release> \ No newline at end of file