aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLadislav Zezula <zezula@volny.cz>2020-11-18 19:12:53 +0100
committerLadislav Zezula <zezula@volny.cz>2020-11-18 19:12:53 +0100
commitb13aaed6d0a940934dcb26aa3cb28ffc0dd06c48 (patch)
tree4886ebc5f1aba7695a5bcc96baa6e97885b8c045 /src
parent725327a23b0ad9a148521353697eb4b27e3f7631 (diff)
Fixed some variants of NP_Protect-ed maps
Diffstat (limited to 'src')
-rw-r--r--src/SBaseCommon.cpp2
-rw-r--r--src/SBaseFileTable.cpp97
-rw-r--r--src/SFileOpenArchive.cpp5
-rw-r--r--src/StormLib.h20
4 files changed, 73 insertions, 51 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp
index 34a7a25..97ebc59 100644
--- a/src/SBaseCommon.cpp
+++ b/src/SBaseCommon.cpp
@@ -962,7 +962,7 @@ void * LoadMpqTable(
}
}
- // If everything succeeded, read the raw table form the MPQ
+ // If everything succeeded, read the raw table from the MPQ
if(FileStream_Read(ha->pStream, &ByteOffset, pbToRead, dwBytesToRead))
{
// First of all, decrypt the table
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index e08daef..af8d290 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -57,11 +57,11 @@ static DWORD GetNecessaryBitCount(ULONGLONG MaxValue)
}
//-----------------------------------------------------------------------------
-// Implementation of the TStormBits struc
+// Implementation of the TMPQBits struct
-struct TStormBits
+struct TMPQBits
{
- static TStormBits * Create(DWORD NumberOfBits, BYTE FillValue);
+ static TMPQBits * Create(DWORD NumberOfBits, BYTE FillValue);
void GetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
void SetBits(unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultSize);
@@ -73,17 +73,17 @@ struct TStormBits
BYTE Elements[1]; // Array of elements (variable length)
};
-const USHORT TStormBits::SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
+const USHORT TMPQBits::SetBitsMask[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
-TStormBits * TStormBits::Create(
+TMPQBits * TMPQBits::Create(
DWORD NumberOfBits,
BYTE FillValue)
{
- TStormBits * pBitArray;
- size_t nSize = sizeof(TStormBits) + (NumberOfBits + 7) / 8;
+ TMPQBits * pBitArray;
+ size_t nSize = sizeof(TMPQBits) + (NumberOfBits + 7) / 8;
// Allocate the bit array
- pBitArray = (TStormBits *)STORM_ALLOC(BYTE, nSize);
+ pBitArray = (TMPQBits *)STORM_ALLOC(BYTE, nSize);
if(pBitArray != NULL)
{
memset(pBitArray, FillValue, nSize);
@@ -94,7 +94,7 @@ TStormBits * TStormBits::Create(
return pBitArray;
}
-void TStormBits::GetBits(
+void TMPQBits::GetBits(
unsigned int nBitPosition,
unsigned int nBitLength,
void * pvBuffer,
@@ -159,7 +159,7 @@ void TStormBits::GetBits(
}
}
-void TStormBits::SetBits(
+void TMPQBits::SetBits(
unsigned int nBitPosition,
unsigned int nBitLength,
void * pvBuffer,
@@ -225,6 +225,11 @@ void TStormBits::SetBits(
}
}
+void GetMPQBits(TMPQBits * pBits, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultByteSize)
+{
+ pBits->GetBits(nBitPosition, nBitLength, pvBuffer, nResultByteSize);
+}
+
//-----------------------------------------------------------------------------
// Support for MPQ header
@@ -234,19 +239,22 @@ static bool VerifyTablePosition64(
ULONGLONG TableSize, // Size of the MPQ table, in bytes
ULONGLONG FileSize) // Size of the entire file, in bytes
{
- // Verify overflows
- if((MpqOffset + TableOffset) < MpqOffset)
- return false;
- if((MpqOffset + TableOffset + TableSize) < MpqOffset)
- return false;
-
- // Verify sizes
- if(TableOffset >= FileSize || TableSize >= FileSize)
- return false;
- if((MpqOffset + TableOffset) >= FileSize)
- return false;
- if((MpqOffset + TableOffset + TableSize) >= FileSize)
- return false;
+ if(TableOffset != 0)
+ {
+ // Verify overflows
+ if((MpqOffset + TableOffset) < MpqOffset)
+ return false;
+ if((MpqOffset + TableOffset + TableSize) < MpqOffset)
+ return false;
+
+ // Verify sizes
+ if(TableOffset >= FileSize || TableSize >= FileSize)
+ return false;
+ if((MpqOffset + TableOffset) >= FileSize)
+ return false;
+ if((MpqOffset + TableOffset + TableSize) >= FileSize)
+ return false;
+ }
return true;
}
@@ -333,10 +341,21 @@ static ULONGLONG DetermineArchiveSize_V4(
// This could only be called for MPQs version 4
assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_4);
- // Determine the archive size as the greatest of all valid values
- EndOfTable = pHeader->BetTablePos64 + pHeader->BetTableSize64;
- if(EndOfTable > ArchiveSize)
- ArchiveSize = EndOfTable;
+ // Check position of BET table, if correct
+ if((pHeader->BetTablePos64 >> 0x20) == 0 && (pHeader->BetTableSize64 >> 0x20) == 0)
+ {
+ EndOfTable = pHeader->BetTablePos64 + pHeader->BetTableSize64;
+ if(EndOfTable > ArchiveSize)
+ ArchiveSize = EndOfTable;
+ }
+
+ // Check position of HET table, if correct
+ if((pHeader->HetTablePos64 >> 0x20) == 0 && (pHeader->HetTableSize64 >> 0x20) == 0)
+ {
+ EndOfTable = pHeader->HetTablePos64 + pHeader->HetTableSize64;
+ if(EndOfTable > ArchiveSize)
+ ArchiveSize = EndOfTable;
+ }
EndOfTable = pHeader->dwHashTablePos + pHeader->dwHashTableSize * sizeof(TMPQHash);
if(EndOfTable > ArchiveSize)
@@ -346,10 +365,6 @@ static ULONGLONG DetermineArchiveSize_V4(
if(EndOfTable > ArchiveSize)
ArchiveSize = EndOfTable;
- EndOfTable = pHeader->HetTablePos64 + pHeader->HetTableSize64;
- if(EndOfTable > ArchiveSize)
- ArchiveSize = EndOfTable;
-
// Return the calculated archive size
return ArchiveSize;
}
@@ -628,6 +643,8 @@ int ConvertMpqHeaderToFormat4(
return ERROR_FAKE_MPQ_HEADER;
if(!VerifyTablePosition64(MpqOffset, pHeader->HiBlockTablePos64, pHeader->HiBlockTableSize64, FileSize))
return ERROR_FAKE_MPQ_HEADER;
+ if(!VerifyTablePosition64(MpqOffset, pHeader->HetTablePos64, pHeader->HetTableSize64, FileSize))
+ return ERROR_FAKE_MPQ_HEADER;
// Check for malformed MPQs
if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ha->MpqPos + pHeader->ArchiveSize64) != FileSize || (ha->MpqPos + pHeader->HiBlockTablePos64) >= FileSize)
@@ -1332,7 +1349,7 @@ TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwNa
memset(pHetTable->pNameHashes, 0, dwTotalCount);
// Allocate the bit array for file indexes
- pHetTable->pBetIndexes = TStormBits::Create(dwTotalCount * pHetTable->dwIndexSizeTotal, 0xFF);
+ pHetTable->pBetIndexes = TMPQBits::Create(dwTotalCount * pHetTable->dwIndexSizeTotal, 0xFF);
if(pHetTable->pBetIndexes != NULL)
{
// Initialize the HET table from the source data (if given)
@@ -1732,7 +1749,7 @@ static TMPQBetTable * TranslateBetTable(
}
// Load the bit-based file table
- pBetTable->pFileTable = TStormBits::Create(pBetTable->dwTableEntrySize * pBetHeader->dwEntryCount, 0);
+ pBetTable->pFileTable = TMPQBits::Create(pBetTable->dwTableEntrySize * pBetHeader->dwEntryCount, 0);
if(pBetTable->pFileTable != NULL)
{
LengthInBytes = (pBetTable->pFileTable->NumberOfBits + 7) / 8;
@@ -1746,7 +1763,7 @@ static TMPQBetTable * TranslateBetTable(
pBetTable->dwBitCount_NameHash2 = pBetHeader->dwBitCount_NameHash2;
// Create and load the array of BET hashes
- pBetTable->pNameHashes = TStormBits::Create(pBetTable->dwBitTotal_NameHash2 * pBetHeader->dwEntryCount, 0);
+ pBetTable->pNameHashes = TMPQBits::Create(pBetTable->dwBitTotal_NameHash2 * pBetHeader->dwEntryCount, 0);
if(pBetTable->pNameHashes != NULL)
{
LengthInBytes = (pBetTable->pNameHashes->NumberOfBits + 7) / 8;
@@ -1771,7 +1788,7 @@ TMPQExtHeader * TranslateBetTable(
TMPQBetHeader BetHeader;
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
TFileEntry * pFileEntry;
- TStormBits * pBitArray = NULL;
+ TMPQBits * pBitArray = NULL;
LPBYTE pbLinearTable = NULL;
LPBYTE pbTrgData;
DWORD LengthInBytes;
@@ -1791,7 +1808,7 @@ TMPQExtHeader * TranslateBetTable(
pbTrgData = (LPBYTE)(pBetHeader + 1);
// Save the bit-based block table
- pBitArray = TStormBits::Create(BetHeader.dwEntryCount * BetHeader.dwTableEntrySize, 0);
+ pBitArray = TMPQBits::Create(BetHeader.dwEntryCount * BetHeader.dwTableEntrySize, 0);
if(pBitArray != NULL)
{
DWORD dwFlagIndex = 0;
@@ -1846,7 +1863,7 @@ TMPQExtHeader * TranslateBetTable(
}
// Create bit array for name hashes
- pBitArray = TStormBits::Create(BetHeader.dwBitTotal_NameHash2 * BetHeader.dwEntryCount, 0);
+ pBitArray = TMPQBits::Create(BetHeader.dwBitTotal_NameHash2 * BetHeader.dwEntryCount, 0);
if(pBitArray != NULL)
{
DWORD dwFileIndex = 0;
@@ -2376,7 +2393,7 @@ TMPQHetTable * LoadHetTable(TMPQArchive * ha)
TMPQHeader * pHeader = ha->pHeader;
// If the HET table position is not 0, we expect the table to be present
- if(pHeader->HetTablePos64 != 0 && pHeader->HetTableSize64 != 0)
+ if(pHeader->HetTablePos64 && pHeader->HetTableSize64)
{
// Attempt to load the HET table (Hash Extended Table)
pExtTable = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE);
@@ -2398,7 +2415,7 @@ TMPQBetTable * LoadBetTable(TMPQArchive * ha)
TMPQHeader * pHeader = ha->pHeader;
// If the BET table position is not 0, we expect the table to be present
- if(pHeader->BetTablePos64 != 0 && pHeader->BetTableSize64 != 0)
+ if(pHeader->BetTablePos64 && pHeader->BetTableSize64)
{
// Attempt to load the HET table (Hash Extended Table)
pExtTable = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE);
@@ -2518,7 +2535,7 @@ static int BuildFileTable_HetBet(TMPQArchive * ha)
TMPQHetTable * pHetTable = ha->pHetTable;
TMPQBetTable * pBetTable;
TFileEntry * pFileEntry = ha->pFileTable;
- TStormBits * pBitArray;
+ TMPQBits * pBitArray;
DWORD dwBitPosition = 0;
DWORD i;
int nError = ERROR_FILE_CORRUPT;
diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp
index 2020e56..d1cc4d6 100644
--- a/src/SFileOpenArchive.cpp
+++ b/src/SFileOpenArchive.cpp
@@ -5,7 +5,7 @@
/* E-mail : ladik@zezula.net */
/* WWW : www.zezula.net */
/*---------------------------------------------------------------------------*/
-/* Archive functions of Storm.dll */
+/* Implementation of archive functions */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
@@ -100,6 +100,7 @@ static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize)
{
TMPQHeader * pHeader = ha->pHeader;
ULONGLONG ByteOffset;
+ //bool bMalformed = (ha->dwFlags & MPQ_FLAG_MALFORMED) ? true : false;
// Check the begin of HET table
if(pHeader->HetTablePos64)
@@ -298,7 +299,7 @@ bool WINAPI SFileOpenArchive(
// If there is the MPQ user data, process it
// Note that Warcraft III does not check for user data, which is abused by many map protectors
dwHeaderID = BSWAP_INT32_UNSIGNED(ha->HeaderData[0]);
- if(MapType == MapTypeNotRecognized && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
+ if(MapType != MapTypeWarcraft3 && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0)
{
if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA)
{
diff --git a/src/StormLib.h b/src/StormLib.h
index 4f19772..d913a54 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -480,7 +480,7 @@ typedef void (WINAPI * SFILE_ADDFILE_CALLBACK)(void * pvUserData, DWORD dwBytesW
typedef void (WINAPI * SFILE_COMPACT_CALLBACK)(void * pvUserData, DWORD dwWorkType, ULONGLONG BytesProcessed, ULONGLONG TotalBytes);
struct TFileStream;
-struct TStormBits;
+struct TMPQBits;
//-----------------------------------------------------------------------------
// Structures related to MPQ format
@@ -748,7 +748,7 @@ typedef struct _TMPQBetHeader
// Structure for parsed HET table
typedef struct _TMPQHetTable
{
- TStormBits * pBetIndexes; // Bit array of FileIndex values
+ TMPQBits * pBetIndexes; // Bit array of FileIndex values
LPBYTE pNameHashes; // Array of NameHash1 values (NameHash1 = upper 8 bits of FileName hashe)
ULONGLONG AndMask64; // AND mask used for calculating file name hash
ULONGLONG OrMask64; // OR mask used for setting the highest bit of the file name hash
@@ -764,8 +764,8 @@ typedef struct _TMPQHetTable
// Structure for parsed BET table
typedef struct _TMPQBetTable
{
- TStormBits * pNameHashes; // Array of NameHash2 entries (lower 24 bits of FileName hash)
- TStormBits * pFileTable; // Bit-based file table
+ TMPQBits * pNameHashes; // Array of NameHash2 entries (lower 24 bits of FileName hash)
+ TMPQBits * pFileTable; // Bit-based file table
LPDWORD pFileFlags; // Array of file flags
DWORD dwTableEntrySize; // Size of one table entry, in bits
@@ -925,10 +925,15 @@ typedef struct _SFILE_CREATE_MPQ
} SFILE_CREATE_MPQ, *PSFILE_CREATE_MPQ;
//-----------------------------------------------------------------------------
+// TMPQBits support - functions
+
+void GetMPQBits(TMPQBits * pBits, unsigned int nBitPosition, unsigned int nBitLength, void * pvBuffer, int nResultByteSize);
+
+//-----------------------------------------------------------------------------
// Stream support - functions
// Structure used by FileStream_GetBitmap
-typedef struct _TStreamBitmap
+struct TStreamBitmap
{
ULONGLONG StreamSize; // Size of the stream, in bytes
DWORD BitmapSize; // Size of the block map, in bytes
@@ -937,8 +942,7 @@ typedef struct _TStreamBitmap
DWORD IsComplete; // Nonzero if the file is complete
// Followed by the BYTE array, each bit means availability of one block
-
-} TStreamBitmap;
+};
// UNICODE versions of the file access functions
TFileStream * FileStream_CreateFile(const TCHAR * szFileName, DWORD dwStreamFlags);
@@ -948,7 +952,7 @@ size_t FileStream_Prefix(const TCHAR * szFileName, DWORD * pdwProvider);
bool FileStream_SetCallback(TFileStream * pStream, SFILE_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData);
-bool FileStream_GetBitmap(TFileStream * pStream, void * pvBitmap, DWORD cbBitmap, LPDWORD pcbLengthNeeded);
+bool FileStream_GetBitmap(TFileStream * pStream, void * pvBitmap, DWORD cbBitmap, DWORD * pcbLengthNeeded);
bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead);
bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite);
bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize);