aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadislav Zezula <zezula@volny.cz>2023-06-07 19:56:08 +0200
committerLadislav Zezula <zezula@volny.cz>2023-06-07 19:56:08 +0200
commit2eab5a3039cff3a8adc5f9510df87452ce56dd2a (patch)
tree4c9cd17bea06296ce1819a1802cece97b01d96fe
parent8732011a322899a960b85b9f5be49e3e626a7c4f (diff)
Version incremented
-rw-r--r--src/SBaseFileTable.cpp100
-rw-r--r--src/StormLib.h4
-rwxr-xr-xtest/StormTest.cpp2
-rw-r--r--test/stormlib-test-001.txt6
4 files changed, 32 insertions, 80 deletions
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index 20d7cc4..befe40f 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -312,59 +312,38 @@ static ULONGLONG DetermineArchiveSize_V1(
return (EndOfMpq - MpqOffset);
}
-static ULONGLONG DetermineArchiveSize_V2(
- TMPQHeader * pHeader,
- ULONGLONG MpqOffset,
- ULONGLONG FileSize)
+static ULONGLONG DetermineBlockTableSize_V2(TMPQHeader * pHeader, ULONGLONG MpqHeaderPos, ULONGLONG FileSize)
{
- ULONGLONG TableOffset;
- ULONGLONG TableSize;
- ULONGLONG MaxOffset = 0;
-
- // This could only be called for MPQs version 2.0
- assert(pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2);
+ ULONGLONG BlockTablePos = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
+ ULONGLONG ArchiveSize = FileSize - MpqHeaderPos;
- // Is the hash table end greater than max offset?
- TableOffset = MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos);
- TableSize = (ULONGLONG)pHeader->dwHashTableSize * sizeof(TMPQHash);
- if((TableOffset + TableSize) > MaxOffset)
- MaxOffset = TableOffset + TableSize;
-
- // Is the block table end greater than max offset?
- TableOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- TableSize = (ULONGLONG)pHeader->dwBlockTableSize * sizeof(TMPQBlock);
- if((TableOffset + TableSize) > MaxOffset)
- MaxOffset = TableOffset + TableSize;
-
- // Is the hi-block table end greater than max offset?
- if((TableOffset = pHeader->HiBlockTablePos64) != 0)
+ // If there is a hi-block table and it is beyond the block table,
+ // we can determine the block table size from it
+ if(pHeader->HiBlockTablePos64 != 0)
{
- TableSize = (ULONGLONG)pHeader->dwBlockTableSize * sizeof(USHORT);
- if((TableOffset + TableSize) > MaxOffset)
- MaxOffset = TableOffset + TableSize;
+ if(pHeader->HiBlockTablePos64 > BlockTablePos)
+ {
+ return (pHeader->HiBlockTablePos64 - BlockTablePos);
+ }
}
- // Cut to the file size
- if(MaxOffset > (FileSize - MpqOffset))
- MaxOffset = FileSize - MpqOffset;
- return MaxOffset;
-}
-
-static ULONGLONG DetermineBlockTableSize_V2(TMPQHeader * pHeader)
-{
- ULONGLONG BlockTableOffset = MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos);
- ULONGLONG TableOffset;
- ULONGLONG TableSize = (pHeader->ArchiveSize64 - BlockTableOffset);
-
- // Subtract the offset of the hi-block table
- if((TableOffset = pHeader->HiBlockTablePos64) != 0)
+ // If we have valid archive size, we can determine the block table size from the archive size
+ else
{
- if(TableOffset > BlockTableOffset)
+ if((BlockTablePos >> 0x20) == 0 && (ArchiveSize >> 0x20) == 0)
{
- TableSize = TableOffset - BlockTableOffset;
+ DWORD dwBlockTablePos32 = (DWORD)(BlockTablePos);
+ DWORD dwArchiveSize32 = (DWORD)(ArchiveSize);
+
+ if(pHeader->dwArchiveSize == dwArchiveSize32)
+ {
+ return (dwArchiveSize32 - dwBlockTablePos32);
+ }
}
}
- return TableSize;
+
+ // Default is the block table size from MPQ header
+ return (ULONGLONG)(pHeader->dwBlockTableSize) * sizeof(TMPQBlock);
}
static ULONGLONG DetermineArchiveSize_V4(
@@ -566,35 +545,14 @@ DWORD ConvertMpqHeaderToFormat4(
// We require the block table to follow hash table
if(BlockTablePos64 >= HashTablePos64)
{
- // HashTableSize64 may be less than TblSize * sizeof(TMPQHash).
- // That means that the hash table is compressed.
+ // Determine whether the hash table is compressed. This can be detected
+ // by subtracting hash table position from the block table position.
pHeader->HashTableSize64 = BlockTablePos64 - HashTablePos64;
- // Calculate the compressed block table size
- if(pHeader->HiBlockTablePos64 != 0)
- {
- // BlockTableSize64 may be less than TblSize * sizeof(TMPQBlock).
- // That means that the block table is compressed.
- pHeader->BlockTableSize64 = pHeader->HiBlockTablePos64 - BlockTablePos64;
- assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
-
- // Determine real archive size
- pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
-
- // Calculate the size of the hi-block table
- pHeader->HiBlockTableSize64 = pHeader->ArchiveSize64 - pHeader->HiBlockTablePos64;
- assert(pHeader->HiBlockTableSize64 == (pHeader->dwBlockTableSize * sizeof(USHORT)));
- }
- else
- {
- // Determine real archive size
- pHeader->ArchiveSize64 = DetermineArchiveSize_V2(pHeader, ByteOffset, FileSize);
- pHeader->dwArchiveSize = (DWORD)(pHeader->ArchiveSize64);
-
- // Calculate size of the block table
- pHeader->BlockTableSize64 = DetermineBlockTableSize_V2(pHeader);
- assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
- }
+ // Also, block table may be compressed. We check whether the HiBlockTable is there.
+ // If not, we try to use the archive size. Note that ArchiveSize may have
+ // an arbitrary value, because it is not tested by Blizzard games anymore
+ pHeader->BlockTableSize64 = DetermineBlockTableSize_V2(pHeader, ByteOffset, FileSize);
}
else
{
diff --git a/src/StormLib.h b/src/StormLib.h
index 94e9813..4aa51c1 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -143,8 +143,8 @@ extern "C" {
//-----------------------------------------------------------------------------
// Defines
-#define STORMLIB_VERSION 0x0918 // Current version of StormLib (9.24)
-#define STORMLIB_VERSION_STRING "9.24" // String version of StormLib version
+#define STORMLIB_VERSION 0x0919 // Current version of StormLib
+#define STORMLIB_VERSION_STRING "9.25" // Current version of StormLib as string
#define ID_MPQ 0x1A51504D // MPQ archive header ID ('MPQ\x1A')
#define ID_MPQ_USERDATA 0x1B51504D // MPQ userdata entry ('MPQ\x1B')
diff --git a/test/StormTest.cpp b/test/StormTest.cpp
index 249cc80..a65430d 100755
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -2655,7 +2655,7 @@ static DWORD TestOpenArchive(
}
// Reset error code, if the failure is expected
- if((dwErrCode != ERROR_SUCCESS) && (hMpq == NULL) && (dwFlags & TFLG_WILL_FAIL))
+ if((dwErrCode != ERROR_SUCCESS || hMpq == NULL) && (dwFlags & TFLG_WILL_FAIL))
SetLastError(dwErrCode = ERROR_SUCCESS);
// Cleanup and exit
diff --git a/test/stormlib-test-001.txt b/test/stormlib-test-001.txt
index f35c06f..d69a56e 100644
--- a/test/stormlib-test-001.txt
+++ b/test/stormlib-test-001.txt
@@ -1,7 +1,3 @@
-Microsoft Windows [Version 10.0.19045.2965]
-(c) Microsoft Corporation. All rights reserved.
-
-E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release>StormLib_test.exe
==== Test Suite for StormLib version 9.24 ====
InitWorkFolder: Work directory \Multimedia\MPQs (default)
TestLiFiSearch (FLAT-MAP:ListFile_Blizzard.txt) succeeded.
@@ -138,5 +134,3 @@ ListFilePos (StormLibTest_ListFilePos.mpq) succeeded.
TestBigArchive (StormLibTest_BigArchive_v4.mpq) succeeded.
TestModifyMpq (MPQ_2014_v4_Base.StormReplay) succeeded.
TestModifyMpq (MPQ_2022_v1_v4.329.w3x) succeeded.
-
-E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release> \ No newline at end of file