From 2fb1a0939fd6174a1e6564d0a87baa3739a64817 Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Tue, 6 Jun 2023 15:36:07 +0200 Subject: Cosmetics --- src/SCompression.cpp | 48 ++++++++++++++++++++++++++++-------------------- src/SFileOpenArchive.cpp | 19 +++++++++++-------- src/StormLib.h | 20 +++++++++++--------- test/StormTest.cpp | 38 +++++++++++++++++++++++++------------- 4 files changed, 75 insertions(+), 50 deletions(-) diff --git a/src/SCompression.cpp b/src/SCompression.cpp index 659c9a8..b689063 100644 --- a/src/SCompression.cpp +++ b/src/SCompression.cpp @@ -895,6 +895,16 @@ int WINAPI SCompCompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuff /* */ /*****************************************************************************/ +// Decompression table specific for Starcraft I BETA +// WAVE files are compressed by different ADPCM compression +static TDecompressTable dcmp_table_sc_beta[] = +{ + {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library + {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression + {0x10, Decompress_ADPCM1_sc1b}, // IMA ADPCM mono decompression + {0x20, Decompress_ADPCM2_sc1b}, // IMA ADPCM stereo decompression +}; + // This table contains decompress functions which can be applied to // uncompressed data. The compression mask is stored in the first byte // of compressed data @@ -909,25 +919,22 @@ static TDecompressTable dcmp_table[] = {MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression }; -// Decompression table specific for Starcraft I BETA -// WAVE files are compressed by different ADPCM compression -static TDecompressTable dcmp_table_sc1b[] = -{ - {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library - {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression - {0x10, Decompress_ADPCM1_sc1b}, // IMA ADPCM mono decompression - {0x20, Decompress_ADPCM2_sc1b}, // IMA ADPCM stereo decompression -}; - -static int SCompDecompressInternal(TDecompressTable * table, size_t table_length, void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +static int SCompDecompressInternal( + TDecompressTable * table, + size_t table_length, + void * pvOutBuffer, + int * pcbOutBuffer, + void * pvInBuffer, + int cbInBuffer, + unsigned uValidMask = 0xFF) { unsigned char * pbWorkBuffer = NULL; unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; unsigned char * pbInBuffer = (unsigned char *)pvInBuffer; unsigned char * pbOutput = (unsigned char *)pvOutBuffer; unsigned char * pbInput; - unsigned uCompressionMask; // Decompressions applied to the data - unsigned uCompressionCopy; // Decompressions applied to the data + unsigned uCompressionMask1; // Decompressions applied to the data + unsigned uCompressionMask2; // Decompressions applied to the data int cbOutBuffer = *pcbOutBuffer; // Current size of the output buffer int cbInLength; // Current size of the input buffer int nCompressCount = 0; // Number of compressions to be applied @@ -948,7 +955,8 @@ static int SCompDecompressInternal(TDecompressTable * table, size_t table_length } // Get applied compression types and decrement data length - uCompressionMask = uCompressionCopy = (unsigned char)(*pbInBuffer++); + uCompressionMask1 = ((unsigned char)(*pbInBuffer++) & (uValidMask)); + uCompressionMask2 = uCompressionMask1; cbInBuffer--; // Get current compressed data and length of it @@ -956,21 +964,21 @@ static int SCompDecompressInternal(TDecompressTable * table, size_t table_length cbInLength = cbInBuffer; // This compression function doesn't support LZMA - assert(uCompressionMask != MPQ_COMPRESSION_LZMA); + assert(uCompressionMask1 != MPQ_COMPRESSION_LZMA); // Parse the compression mask for(size_t i = 0; i < table_length; i++) { // If the mask agrees, insert the compression function to the array - if(uCompressionMask & table[i].uMask) + if(uCompressionMask1 & table[i].uMask) { - uCompressionCopy &= ~table[i].uMask; + uCompressionMask2 &= ~table[i].uMask; nCompressCount++; } } // If at least one of the compressions remaing unknown, return an error - if(nCompressCount == 0 || uCompressionCopy != 0) + if(nCompressCount == 0 || uCompressionMask2 != 0) { SetLastError(ERROR_NOT_SUPPORTED); return 0; @@ -994,7 +1002,7 @@ static int SCompDecompressInternal(TDecompressTable * table, size_t table_length for(size_t i = 0; i < table_length; i++) { // Perform the (next) decompression - if(uCompressionMask & table[i].uMask) + if(uCompressionMask1 & table[i].uMask) { // Get the correct output buffer pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer; @@ -1032,7 +1040,7 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) { - return SCompDecompressInternal(dcmp_table_sc1b, _countof(dcmp_table_sc1b), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); + return SCompDecompressInternal(dcmp_table_sc_beta, _countof(dcmp_table_sc_beta), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); } int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp index 16e2491..f19a6e7 100644 --- a/src/SFileOpenArchive.cpp +++ b/src/SFileOpenArchive.cpp @@ -463,16 +463,19 @@ bool WINAPI SFileOpenArchive( if(IsStarcraftBetaArchive(ha->pHeader)) ha->dwFlags |= MPQ_FLAG_STARCRAFT_BETA; - // Remember whether whis is a map for Warcraft III - if(MapType == MapTypeWarcraft3) + // Maps from StarCraft and Warcraft III need special treatment + switch(MapType) { - ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_W3X; - ha->dwFlags |= MPQ_FLAG_WAR3_MAP; - } + case MapTypeStarcraft: + ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_SCX; + ha->dwFlags |= MPQ_FLAG_STARCRAFT; + break; - // If this is starcraft map, set the flag mask - if(MapType == MapTypeStarcraft) - ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_SCX; + case MapTypeWarcraft3: + ha->dwValidFileFlags = MPQ_FILE_VALID_FLAGS_W3X; + ha->dwFlags |= MPQ_FLAG_WAR3_MAP; + break; + } // Set the size of file sector ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize); diff --git a/src/StormLib.h b/src/StormLib.h index 07408b2..5142868 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -194,15 +194,16 @@ extern "C" { #define MPQ_FLAG_CHECK_SECTOR_CRC 0x00000020 // Checking sector CRC when reading files #define MPQ_FLAG_SAVING_TABLES 0x00000040 // If set, we are saving MPQ internal files and MPQ tables #define MPQ_FLAG_PATCH 0x00000080 // If set, this MPQ is a patch archive -#define MPQ_FLAG_WAR3_MAP 0x00000100 // If set, this MPQ is a Warcraft III map -#define MPQ_FLAG_STARCRAFT_BETA 0x00000200 // If set, this MPQ is StarDat.mpq from Starcraft I BETA -#define MPQ_FLAG_LISTFILE_NONE 0x00000400 // Set when no (listfile) was found in InvalidateInternalFiles -#define MPQ_FLAG_LISTFILE_NEW 0x00000800 // Set when (listfile) invalidated by InvalidateInternalFiles -#define MPQ_FLAG_LISTFILE_FORCE 0x00001000 // Save updated listfile on exit -#define MPQ_FLAG_ATTRIBUTES_NONE 0x00002000 // Set when no (attributes) was found in InvalidateInternalFiles -#define MPQ_FLAG_ATTRIBUTES_NEW 0x00004000 // Set when (attributes) invalidated by InvalidateInternalFiles -#define MPQ_FLAG_SIGNATURE_NONE 0x00008000 // Set when no (signature) was found in InvalidateInternalFiles -#define MPQ_FLAG_SIGNATURE_NEW 0x00010000 // Set when (signature) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_STARCRAFT_BETA 0x00000100 // If set, this MPQ is from Starcraft I BETA +#define MPQ_FLAG_STARCRAFT 0x00000200 // If set, this MPQ is from Starcraft I +#define MPQ_FLAG_WAR3_MAP 0x00000400 // If set, this MPQ is a Warcraft III map +#define MPQ_FLAG_LISTFILE_NONE 0x00000800 // Set when no (listfile) was found in InvalidateInternalFiles +#define MPQ_FLAG_LISTFILE_NEW 0x00001000 // Set when (listfile) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_LISTFILE_FORCE 0x00002000 // Save updated listfile on exit +#define MPQ_FLAG_ATTRIBUTES_NONE 0x00004000 // Set when no (attributes) was found in InvalidateInternalFiles +#define MPQ_FLAG_ATTRIBUTES_NEW 0x00008000 // Set when (attributes) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_SIGNATURE_NONE 0x00010000 // Set when no (signature) was found in InvalidateInternalFiles +#define MPQ_FLAG_SIGNATURE_NEW 0x00020000 // Set when (signature) invalidated by InvalidateInternalFiles // Values for TMPQArchive::dwSubType #define MPQ_SUBTYPE_MPQ 0x00000000 // The file is a MPQ file (Blizzard games) @@ -1122,6 +1123,7 @@ int WINAPI SCompCompress (void * pvOutBuffer, int * pcbOutBuffer, void * pv int WINAPI SCompDecompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); +//int WINAPI SCompDecompress_SCBW(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); //----------------------------------------------------------------------------- // Non-Windows support for SetLastError/GetLastError diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 82668cf..dc63bdc 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -4055,6 +4055,9 @@ static const TEST_INFO Test_OpenMpqs[] = {_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, "10e4dcdbe95b7ad731c563ec6b71bc16", 82}, // Encrypted archive from Starcraft II installer {_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"),NULL, "d41d8cd98f00b204e9800998ecf8427e", 14263}, // Partial MPQ with compressed hash table {_T("blk4-file://streaming/model.MPQ.0"), NULL, "e06b00efb2fc7e7469dd8b3b859ae15d", 39914}, // Archive that is merged with multiple files + {_T("MPQ_2023_v2_MemoryCorruption.SC2Replay"), NULL, "4cf5021aa272298e64712a378a50df44", 10}, // MPQ archive v 2.0, archive size is wrong + {_T("MPQ_2023_v1_StarcraftMap.scm"), NULL, "7830c51700697dd3c175f086a3157b29", 4}, // StarCraft map from StarCraft: Brood War 1.16 + {_T("MPQ_2023_v1_BroodWarMap.scx"), NULL, "dd3afa3c2f5e562ce3ca91c0c605a71f", 3}, // Brood War map from StarCraft: Brood War 1.16 // Protected archives {_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"), NULL, "b900364cc134a51ddeca21a13697c3ca", 79}, @@ -4165,9 +4168,9 @@ static const TEST_INFO Test_Signature[] = // Main //#define TEST_COMMAND_LINE -#define TEST_LOCAL_LISTFILE -#define TEST_STREAM_OPERATIONS -#define TEST_MASTER_MIRROR +//#define TEST_LOCAL_LISTFILE +//#define TEST_STREAM_OPERATIONS +//#define TEST_MASTER_MIRROR #define TEST_OPEN_MPQ #define TEST_REOPEN_MPQ #define TEST_VERIFY_SIGNATURE @@ -4183,20 +4186,29 @@ int _tmain(int argc, TCHAR * argv[]) // Initialize storage and mix the random number generator printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING); dwErrCode = InitializeMpqDirectory(argv, argc); - - // Check creation of the MPQ with LZMA compression - LPCTSTR szArchiveName = _T("e:\\MemoryCorruption.SC2Replay"); +/* + // Check opening of a MPQ + LPCTSTR szArchiveName = _T("e:\\Volcanis.scm"); + LPBYTE pbBuffer = NULL; HANDLE hFile = NULL; HANDLE hMpq = NULL; -/* + DWORD dwFileSize; + if(SFileOpenArchive(szArchiveName, 0, 0, &hMpq)) { - if(SFileOpenFileEx(hMpq, "DlgSearchFile.cpp", 0, &hFile)) + if(SFileOpenFileEx(hMpq, "staredit\\scenario.chk", 0, &hFile)) { - DWORD dwBytesRead = 0; - BYTE Buffer[0x100]; + if((dwFileSize = SFileGetFileSize(hFile, NULL)) != NULL) + { + if((pbBuffer = STORM_ALLOC(BYTE, dwFileSize)) != NULL) + { + DWORD dwBytesRead = 0; - SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); + SFileReadFile(hFile, pbBuffer, dwFileSize, &dwBytesRead, NULL); + assert(dwBytesRead == dwFileSize); + STORM_FREE(pbBuffer); + } + } SFileCloseFile(hFile); } SFileCloseArchive(hMpq); @@ -4205,9 +4217,9 @@ int _tmain(int argc, TCHAR * argv[]) #ifdef TEST_COMMAND_LINE // Test-open MPQs from the command line. They must be plain name // and must be placed in the Test-MPQs folder - for(int i = 2; i < argc; i++) + for(int i = 1; i < argc; i++) { - TestOpenArchive(argv[i], Bliz, 0, "Scripts\\War3map.j", NULL); + TestOpenArchive(argv[i], NULL, NULL, 0, &LfBliz); } #endif // TEST_COMMAND_LINE -- cgit v1.2.3