diff options
author | Ladislav Zezula <zezula@volny.cz> | 2020-12-13 12:32:25 +0100 |
---|---|---|
committer | Ladislav Zezula <zezula@volny.cz> | 2020-12-13 12:32:25 +0100 |
commit | 383e1572eecafdfe4f92ddad7a4bece069e12f38 (patch) | |
tree | 9c419d10e4cb4e2e569155f91cc93a7fdec62efc /src | |
parent | 866269d740b32cf209e5188c5269c4118f8be07b (diff) |
Added support for amternative MPQ markers
Diffstat (limited to 'src')
-rw-r--r-- | src/SBaseCommon.cpp | 7 | ||||
-rw-r--r-- | src/SBaseFileTable.cpp | 4 | ||||
-rw-r--r-- | src/SBaseSubTypes.cpp | 4 | ||||
-rw-r--r-- | src/SFileAddFile.cpp | 4 | ||||
-rw-r--r-- | src/SFileCreateArchive.cpp | 2 | ||||
-rw-r--r-- | src/SFileListFile.cpp | 2 | ||||
-rw-r--r-- | src/SFileOpenArchive.cpp | 42 | ||||
-rw-r--r-- | src/SFileOpenFileEx.cpp | 2 | ||||
-rw-r--r-- | src/SFileVerify.cpp | 4 | ||||
-rw-r--r-- | src/StormCommon.h | 5 | ||||
-rw-r--r-- | src/StormLib.h | 13 |
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); |