aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avast.com>2022-09-28 20:15:07 +0200
committerLadislav Zezula <ladislav.zezula@avast.com>2022-09-28 20:15:07 +0200
commit6c113f66819fc3a4934393cc2956036a99887e44 (patch)
treeafee55102a2fa423486f93b5071878c0aa097cd5
parent7a664bf6be4377aabe03f118fcdb6d1d3abc48f5 (diff)
lcLocale -> lcFileLocale. Now also contains platform
-rw-r--r--make-msvc.bat8
-rw-r--r--src/SBaseCommon.cpp17
-rw-r--r--src/SBaseDumpData.cpp2
-rw-r--r--src/SBaseFileTable.cpp39
-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.h17
-rw-r--r--test/StormTest.cpp10
14 files changed, 84 insertions, 71 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..6e589a5 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)
{
@@ -803,16 +805,17 @@ 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
// 2) NULL
-static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale)
+static TMPQHash * GetHashEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcFileLocale)
{
TMPQHash * pFirstHash = GetFirstHashEntry(ha, szFileName);
TMPQHash * pHash = pFirstHash;
+ USHORT Locale = SFILE_LOCALE(lcFileLocale);
// Parse the found hashes
while(pHash != NULL)
{
// If the locales match, return it
- if(pHash->lcLocale == lcLocale)
+ if(pHash->Locale == Locale)
return pHash;
// Get the next hash entry for that file
@@ -1967,7 +1970,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 +1980,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 +2001,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 +2009,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 +2065,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 +2112,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 +2142,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 +2153,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 +2176,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 +2199,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 +2931,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..ce177e6 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 = GetFileEntryLocale(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..483357b 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -627,7 +627,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 +638,7 @@ typedef struct _TMPQHash
BYTE Reserved;
BYTE Platform;
- USHORT lcLocale;
+ USHORT Locale;
#endif
@@ -910,7 +910,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 +994,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 +1090,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..b4c3e9f 100644
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -1402,7 +1402,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 +1421,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))
@@ -2507,7 +2507,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 +2527,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 +2574,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);