aboutsummaryrefslogtreecommitdiff
path: root/src/SBaseFileTable.cpp
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/SBaseFileTable.cpp
parent725327a23b0ad9a148521353697eb4b27e3f7631 (diff)
Fixed some variants of NP_Protect-ed maps
Diffstat (limited to 'src/SBaseFileTable.cpp')
-rw-r--r--src/SBaseFileTable.cpp97
1 files changed, 57 insertions, 40 deletions
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;