aboutsummaryrefslogtreecommitdiff
path: root/src/SBaseFileTable.cpp
diff options
context:
space:
mode:
authorLadislav Zezula <ladislav.zezula@avg.com>2013-12-19 11:23:48 +0100
committerLadislav Zezula <ladislav.zezula@avg.com>2013-12-19 11:23:48 +0100
commitebd502e0c220f7c2d3b9ce65bd83ed569d65f314 (patch)
treecb3c0d82de0432448db4a09e9e0ef6d4e71beacb /src/SBaseFileTable.cpp
parent55f159cf69d8b4816876653d25239abf6c3ef5a4 (diff)
+ Bitmap support was moved from archive functions to FileStream functions, where are more appropriate
+ Added support for master-mirror streams (like Blizzard games do) + SFileGetArchiveBitmap was moved into SFileGetFileInfo + Fixed bug in SFileCompactArchive + Removed classes SFileMpqBitmapXXX from SFileGetFileInfo
Diffstat (limited to 'src/SBaseFileTable.cpp')
-rw-r--r--src/SBaseFileTable.cpp108
1 files changed, 14 insertions, 94 deletions
diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp
index d88c5f9..fe02931 100644
--- a/src/SBaseFileTable.cpp
+++ b/src/SBaseFileTable.cpp
@@ -252,12 +252,22 @@ static DWORD GetMaxFileOffset32(TMPQArchive * ha)
static ULONGLONG DetermineEndOfArchive_V1_V2(
TMPQArchive * ha,
+ TMPQHeader * pHeader,
ULONGLONG MpqOffset,
ULONGLONG FileSize)
{
ULONGLONG ByteOffset;
ULONGLONG EndOfMpq = FileSize;
DWORD SignatureHeader = 0;
+ DWORD dwArchiveSize32;
+
+ // Check if we can rely on the archive size in the header
+ if((FileSize >> 0x20) == 0)
+ {
+ dwArchiveSize32 = (DWORD)(FileSize - MpqOffset);
+ if(pHeader->dwBlockTablePos < pHeader->dwArchiveSize && pHeader->dwArchiveSize <= dwArchiveSize32)
+ return pHeader->dwArchiveSize;
+ }
// Check if there is a signature header
if((EndOfMpq - MpqOffset) > (MPQ_STRONG_SIGNATURE_SIZE + 4))
@@ -375,7 +385,7 @@ int ConvertMpqHeaderToFormat4(
// Determine the archive size on malformed MPQs
if(ha->dwFlags & MPQ_FLAG_MALFORMED)
{
- pHeader->ArchiveSize64 = DetermineEndOfArchive_V1_V2(ha, MpqOffset, FileSize);
+ pHeader->ArchiveSize64 = DetermineEndOfArchive_V1_V2(ha, pHeader, MpqOffset, FileSize);
pHeader->dwArchiveSize = (DWORD)pHeader->ArchiveSize64;
}
break;
@@ -418,7 +428,7 @@ int ConvertMpqHeaderToFormat4(
assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
// Determine the size of the hi-block table
- pHeader->HiBlockTableSize64 = DetermineEndOfArchive_V1_V2(ha, MpqOffset, FileSize) - pHeader->HiBlockTablePos64;
+ pHeader->HiBlockTableSize64 = DetermineEndOfArchive_V1_V2(ha, pHeader, MpqOffset, FileSize) - pHeader->HiBlockTablePos64;
assert(pHeader->HiBlockTableSize64 == (pHeader->dwBlockTableSize * sizeof(USHORT)));
// Recalculate the archive size
@@ -427,7 +437,7 @@ int ConvertMpqHeaderToFormat4(
else
{
// Block table size is the end of the archive minus the block table position
- pHeader->BlockTableSize64 = DetermineEndOfArchive_V1_V2(ha, MpqOffset, FileSize) - BlockTablePos64;
+ pHeader->BlockTableSize64 = DetermineEndOfArchive_V1_V2(ha, pHeader, MpqOffset, FileSize) - BlockTablePos64;
assert(pHeader->BlockTableSize64 <= (pHeader->dwBlockTableSize * sizeof(TMPQBlock)));
// dwArchiveSize in the header v 2.0 is 32-bit only
@@ -1989,96 +1999,6 @@ void InvalidateInternalFiles(TMPQArchive * ha)
}
//-----------------------------------------------------------------------------
-// Functions that loads and verify MPQ data bitmap
-
-int LoadMpqDataBitmap(TMPQArchive * ha, ULONGLONG FileSize, bool * pbFileIsComplete)
-{
- TMPQBitmap * pBitmap = NULL;
- TMPQBitmap DataBitmap;
- ULONGLONG BitmapOffset;
- ULONGLONG EndOfMpq;
- DWORD DataBlockCount = 0;
- DWORD BitmapByteSize = 0;
- DWORD WholeByteCount;
- DWORD ExtraBitsCount;
-
- // Is there enough space for a MPQ bitmap?
- // Note: Do not rely on file size when looking for the bitmap.
- // Battle.net.MPQ from SC2:HOTS (build 22342) has some data appended after the bitmap
- EndOfMpq = ha->MpqPos + ha->pHeader->ArchiveSize64;
- if(FileSize > EndOfMpq && ha->pHeader->dwRawChunkSize != 0)
- {
- // Calculate the number of extra bytes for data bitmap
- DataBlockCount = (DWORD)(((ha->pHeader->ArchiveSize64 - 1) / ha->pHeader->dwRawChunkSize) + 1);
- BitmapByteSize = ((DataBlockCount + 7) / 8);
- BitmapOffset = EndOfMpq + BitmapByteSize;
-
- // Try to load the data bitmap from the end of the file
- if(FileStream_Read(ha->pStream, &BitmapOffset, &DataBitmap, sizeof(TMPQBitmap)))
- {
- // Is it a valid data bitmap?
- BSWAP_ARRAY32_UNSIGNED((LPDWORD)(&DataBitmap), sizeof(TMPQBitmap));
- if(DataBitmap.dwSignature == MPQ_DATA_BITMAP_SIGNATURE)
- {
- // Several sanity checks to ensure integrity of the bitmap
- assert(ha->MpqPos + MAKE_OFFSET64(DataBitmap.dwMapOffsetHi, DataBitmap.dwMapOffsetLo) == EndOfMpq);
- assert(ha->pHeader->dwRawChunkSize == DataBitmap.dwBlockSize);
-
- // Allocate space for the data bitmap
- pBitmap = (TMPQBitmap *)STORM_ALLOC(BYTE, sizeof(TMPQBitmap) + BitmapByteSize);
- if(pBitmap != NULL)
- {
- // Copy the bitmap header
- memcpy(pBitmap, &DataBitmap, sizeof(TMPQBitmap));
-
- // Read the remaining part
- if(!FileStream_Read(ha->pStream, &EndOfMpq, (pBitmap + 1), BitmapByteSize))
- {
- STORM_FREE(pBitmap);
- pBitmap = NULL;
- }
- }
- }
- }
- }
-
- // If the caller asks for file completeness, check it
- if(pBitmap != NULL && pbFileIsComplete != NULL)
- {
- LPBYTE pbBitmap = (LPBYTE)(pBitmap + 1);
- DWORD i;
- bool bFileIsComplete = true;
-
- // Calculate the number of whole bytes and extra bits of the bitmap
- WholeByteCount = (DataBlockCount / 8);
- ExtraBitsCount = (DataBlockCount & 7);
-
- // Verify the whole bytes - their value must be 0xFF
- for(i = 0; i < WholeByteCount; i++)
- {
- if(pbBitmap[i] != 0xFF)
- bFileIsComplete = false;
- }
-
- // If there are extra bits, calculate the mask
- if(ExtraBitsCount != 0)
- {
- BYTE ExpectedValue = (BYTE)((1 << ExtraBitsCount) - 1);
-
- if(pbBitmap[i] != ExpectedValue)
- bFileIsComplete = false;
- }
-
- // Give the result to the caller
- *pbFileIsComplete = bFileIsComplete;
- }
-
- ha->dwBitmapSize = sizeof(TMPQBitmap) + BitmapByteSize;
- ha->pBitmap = pBitmap;
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
// Support for file tables - hash table, block table, hi-block table
int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize)
@@ -2726,7 +2646,6 @@ int RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize, DWORD dwNewMaxF
// Set the new tables to the MPQ archive
ha->pFileTable = pFileTable;
ha->pHashTable = pHashTable;
- pFileTable = NULL;
// Set the new limits to the MPQ archive
ha->pHeader->dwHashTableSize = dwNewHashTableSize;
@@ -2757,6 +2676,7 @@ int RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize, DWORD dwNewMaxF
// Update the file table size
ha->dwFileTableSize = (DWORD)(pFileEntry - pFileTable);
ha->dwFlags |= MPQ_FLAG_CHANGED;
+ pFileTable = NULL;
}
// Now free the remaining entries