aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLadislav Zezula <zezula@volny.cz>2020-12-13 12:32:25 +0100
committerLadislav Zezula <zezula@volny.cz>2020-12-13 12:32:25 +0100
commit383e1572eecafdfe4f92ddad7a4bece069e12f38 (patch)
tree9c419d10e4cb4e2e569155f91cc93a7fdec62efc /src
parent866269d740b32cf209e5188c5269c4118f8be07b (diff)
Added support for amternative MPQ markers
Diffstat (limited to 'src')
-rw-r--r--src/SBaseCommon.cpp7
-rw-r--r--src/SBaseFileTable.cpp4
-rw-r--r--src/SBaseSubTypes.cpp4
-rw-r--r--src/SFileAddFile.cpp4
-rw-r--r--src/SFileCreateArchive.cpp2
-rw-r--r--src/SFileListFile.cpp2
-rw-r--r--src/SFileOpenArchive.cpp42
-rw-r--r--src/SFileOpenFileEx.cpp2
-rw-r--r--src/SFileVerify.cpp4
-rw-r--r--src/StormCommon.h5
-rw-r--r--src/StormLib.h13
11 files changed, 68 insertions, 21 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
index 9003960..700c4a7 100644
--- a/src/SBaseCommon.cpp
+++ b/src/SBaseCommon.cpp
@@ -20,7 +20,10 @@ char StormLibCopyright[] = "StormLib v " STORMLIB_VERSION_STRING " Copyright Lad
//-----------------------------------------------------------------------------
// Local variables
-LCID lcFileLocale = LANG_NEUTRAL; // File locale
+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
//-----------------------------------------------------------------------------
@@ -630,7 +633,7 @@ TMPQArchive * IsValidMpqHandle(HANDLE hMpq)
{
TMPQArchive * ha = (TMPQArchive *)hMpq;
- return (ha != NULL && ha->pHeader != NULL && ha->pHeader->dwID == ID_MPQ) ? ha : NULL;
+ return (ha != NULL && ha->pHeader != NULL && ha->pHeader->dwID == g_dwMpqSignature) ? ha : NULL;
}
TMPQFile * IsValidFileHandle(HANDLE hFile)
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index f9a86a0..aba5e2c 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -2336,7 +2336,7 @@ static TMPQHash * LoadHashTable(TMPQArchive * ha)
dwCmpSize = (DWORD)pHeader->HashTableSize64;
// Read, decrypt and uncompress the hash table
- pHashTable = (TMPQHash *)LoadMpqTable(ha, ByteOffset, pHeader->MD5_HashTable, dwCmpSize, dwTableSize, MPQ_KEY_HASH_TABLE, &bHashTableIsCut);
+ pHashTable = (TMPQHash *)LoadMpqTable(ha, ByteOffset, pHeader->MD5_HashTable, dwCmpSize, dwTableSize, g_dwHashTableKey, &bHashTableIsCut);
// DumpHashTable(pHashTable, pHeader->dwHashTableSize);
// If the hash table was cut, we can/have to defragment it
@@ -2397,7 +2397,7 @@ TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool /* bDontFixEntries */)
dwCmpSize = (DWORD)pHeader->BlockTableSize64;
// Read, decrypt and uncompress the block table
- pBlockTable = (TMPQBlock * )LoadMpqTable(ha, ByteOffset, NULL, dwCmpSize, dwTableSize, MPQ_KEY_BLOCK_TABLE, &bBlockTableIsCut);
+ pBlockTable = (TMPQBlock * )LoadMpqTable(ha, ByteOffset, NULL, dwCmpSize, dwTableSize, g_dwBlockTableKey, &bBlockTableIsCut);
// If the block table was cut, we need to remember it
if(pBlockTable != NULL && bBlockTableIsCut)
diff --git a/src/SBaseSubTypes.cpp b/src/SBaseSubTypes.cpp
index 6ac5279..afa7311 100644
--- a/src/SBaseSubTypes.cpp
+++ b/src/SBaseSubTypes.cpp
@@ -131,7 +131,7 @@ int ConvertSqpHeaderToFormat4(
Header.wSectorSize = BSWAP_INT16_UNSIGNED(pSqpHeader->wSectorSize);
// Verify the SQP header
- if(Header.dwID == ID_MPQ && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize)
+ if(Header.dwID == g_dwMpqSignature && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize)
{
// Check for fixed values of version and sector size
if(Header.wFormatVersion == MPQ_FORMAT_VERSION_1 && Header.wSectorSize == 3)
@@ -414,7 +414,7 @@ int ConvertMpkHeaderToFormat4(
if(Header.dwID == ID_MPK && Header.dwHeaderSize == sizeof(TMPKHeader) && Header.dwArchiveSize == (DWORD)FileSize)
{
// The header ID must be ID_MPQ
- Header.dwID = ID_MPQ;
+ Header.dwID = g_dwMpqSignature;
Header.wFormatVersion = MPQ_FORMAT_VERSION_1;
Header.wSectorSize = 3;
diff --git a/src/SFileAddFile.cpp b/src/SFileAddFile.cpp
index 31f052a..4599ca4 100644
--- a/src/SFileAddFile.cpp
+++ b/src/SFileAddFile.cpp
@@ -954,7 +954,7 @@ bool WINAPI SFileAddFileEx(
}
// Initiate adding file to the MPQ
- if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, lcFileLocale, dwFlags, &hMpqFile))
+ if(!SFileCreateFile(hMpq, szArchivedName, FileTime, (DWORD)FileSize, g_lcFileLocale, dwFlags, &hMpqFile))
nError = GetLastError();
}
@@ -1165,7 +1165,7 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
// Open the new file. If exists, we don't allow rename operation
if(nError == ERROR_SUCCESS)
{
- if(GetFileEntryLocale(ha, szNewFileName, lcFileLocale) != NULL)
+ if(GetFileEntryLocale(ha, szNewFileName, g_lcFileLocale) != NULL)
nError = ERROR_ALREADY_EXISTS;
}
diff --git a/src/SFileCreateArchive.cpp b/src/SFileCreateArchive.cpp
index 7c24491..4185f3d 100644
--- a/src/SFileCreateArchive.cpp
+++ b/src/SFileCreateArchive.cpp
@@ -220,7 +220,7 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea
// Fill the MPQ header
memset(pHeader, 0, sizeof(ha->HeaderData));
- pHeader->dwID = ID_MPQ;
+ pHeader->dwID = g_dwMpqSignature;
pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion;
diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp
index 6fcd736..f94f955 100644
--- a/src/SFileListFile.cpp
+++ b/src/SFileListFile.cpp
@@ -536,7 +536,7 @@ static int SFileAddInternalListFile(
{
TMPQHash * pFirstHash;
TMPQHash * pHash;
- LCID lcSaveLocale = lcFileLocale;
+ LCID lcSaveLocale = g_lcFileLocale;
DWORD dwMaxSize = MAX_LISTFILE_SIZE;
int nError = ERROR_SUCCESS;
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp
index 500e041..1d2c2f9 100644
--- a/src/SFileOpenArchive.cpp
+++ b/src/SFileOpenArchive.cpp
@@ -146,9 +146,37 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
return ERROR_SUCCESS;
}
-/*****************************************************************************/
-/* Public functions */
-/*****************************************************************************/
+//-----------------------------------------------------------------------------
+// Support for alternate markers. Call before SFileOpenArchive
+
+#define SFILE_MARKERS_MIN_SIZE (sizeof(DWORD) + sizeof(DWORD) + sizeof(const char *) + sizeof(const char *))
+
+bool WINAPI SFileSetArchiveMarkers(PSFILE_MARKERS pMarkers)
+{
+ // Check structure minimum size
+ if(pMarkers == NULL || pMarkers->dwSize < SFILE_MARKERS_MIN_SIZE)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Make sure that the MPQ cryptography is initialized at this time
+ InitializeMpqCryptography();
+
+ // Remember the marker for MPQ header
+ g_dwMpqSignature = pMarkers->dwSignature;
+
+ // Remember the encryption key for hash table
+ if(pMarkers->szHashTableKey != NULL)
+ g_dwHashTableKey = HashString(pMarkers->szHashTableKey, MPQ_HASH_FILE_KEY);
+
+ // Remember the encryption key for block table
+ if(pMarkers->szBlockTableKey != NULL)
+ g_dwBlockTableKey = HashString(pMarkers->szBlockTableKey, MPQ_HASH_FILE_KEY);
+
+ // Succeeded
+ return true;
+}
//-----------------------------------------------------------------------------
// SFileGetLocale and SFileSetLocale
@@ -156,13 +184,13 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
LCID WINAPI SFileGetLocale()
{
- return lcFileLocale;
+ return g_lcFileLocale;
}
LCID WINAPI SFileSetLocale(LCID lcNewLocale)
{
- lcFileLocale = lcNewLocale;
- return lcFileLocale;
+ g_lcFileLocale = lcNewLocale;
+ return g_lcFileLocale;
}
//-----------------------------------------------------------------------------
@@ -323,7 +351,7 @@ bool WINAPI SFileOpenArchive(
// Abused by Spazzler Map protector. Note that the size check is not present
// in Storm.dll v 1.00, so Diablo I code would load the MPQ anyway.
dwHeaderSize = BSWAP_INT32_UNSIGNED(ha->HeaderData[1]);
- if(dwHeaderID == ID_MPQ && dwHeaderSize >= MPQ_HEADER_SIZE_V1)
+ if(dwHeaderID == g_dwMpqSignature && dwHeaderSize >= MPQ_HEADER_SIZE_V1)
{
// Now convert the header to version 4
nError = ConvertMpqHeaderToFormat4(ha, ByteOffset, FileSize, dwFlags, MapType);
diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp
index 5b7933a..1e02a22 100644
--- a/src/SFileOpenFileEx.cpp
+++ b/src/SFileOpenFileEx.cpp
@@ -263,7 +263,7 @@ bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearch
// If this MPQ has no patches, open the file from this MPQ directly
if(ha->haPatch == NULL || dwSearchScope == SFILE_OPEN_BASE_FILE)
{
- pFileEntry = GetFileEntryLocale2(ha, szFileName, lcFileLocale, &dwHashIndex);
+ pFileEntry = GetFileEntryLocale2(ha, szFileName, g_lcFileLocale, &dwHashIndex);
}
// If this MPQ is a patched archive, open the file as patched
diff --git a/src/SFileVerify.cpp b/src/SFileVerify.cpp
index 7e8848f..1b885b4 100644
--- a/src/SFileVerify.cpp
+++ b/src/SFileVerify.cpp
@@ -592,7 +592,7 @@ static DWORD VerifyFile(
dwVerifyResult |= VERIFY_FILE_HAS_RAW_MD5;
// Find file entry for the file
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
+ pFileEntry = GetFileEntryLocale(ha, szFileName, g_lcFileLocale);
if(pFileEntry != NULL)
{
// If the file's raw MD5 doesn't match, don't bother with more checks
@@ -964,7 +964,7 @@ int WINAPI SFileVerifyRawData(HANDLE hMpq, DWORD dwWhatToVerify, const char * sz
return ERROR_INVALID_PARAMETER;
// Get the offset of a file
- pFileEntry = GetFileEntryLocale(ha, szFileName, lcFileLocale);
+ pFileEntry = GetFileEntryLocale(ha, szFileName, g_lcFileLocale);
if(pFileEntry == NULL)
return ERROR_FILE_NOT_FOUND;
diff --git a/src/StormCommon.h b/src/StormCommon.h
index 9f9715f..f8023c4 100644
--- a/src/StormCommon.h
+++ b/src/StormCommon.h
@@ -134,7 +134,10 @@ typedef struct _MPQ_SIGNATURE_INFO
//-----------------------------------------------------------------------------
// StormLib internal global variables
-extern LCID lcFileLocale; // Preferred file locale
+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
//-----------------------------------------------------------------------------
// Conversion to uppercase/lowercase (and "/" to "\")
diff --git a/src/StormLib.h b/src/StormLib.h
index 4d9066d..145cf58 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -924,6 +924,14 @@ typedef struct _SFILE_CREATE_MPQ
} SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ;
+typedef struct _SFILE_MARKERS
+{
+ DWORD dwSize; // Size of this structure, in bytes
+ DWORD dwSignature; // Alternate MPQ header marker
+ const char * szHashTableKey; // Replacement for "(hash table)"
+ const char * szBlockTableKey; // Replacement for "(block table)"
+} SFILE_MARKERS, *PSFILE_MARKERS;
+
//-----------------------------------------------------------------------------
// TMPQBits support - functions
@@ -979,6 +987,11 @@ typedef bool (WINAPI * SFILEREADFILE)(HANDLE, void *, DWORD, LPDWORD, LPOVERLAP
//-----------------------------------------------------------------------------
// Functions for manipulation with StormLib global flags
+// 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);