diff options
-rw-r--r-- | Publish.bat | 25 | ||||
-rw-r--r-- | make-msvc.bat | 16 | ||||
-rw-r--r-- | src/DllMain.rc | 24 | ||||
-rw-r--r-- | src/LibTomCrypt.c | 1 | ||||
-rw-r--r-- | src/SBaseCommon.cpp | 3 | ||||
-rw-r--r-- | src/SFileAddFile.cpp | 8 | ||||
-rw-r--r-- | src/StormLib.h | 4 | ||||
-rw-r--r-- | src/libtomcrypt/src/hashes/hash_memory.c | 69 | ||||
-rw-r--r-- | src/libtomcrypt/src/headers/tomcrypt_custom.h | 36 | ||||
-rwxr-xr-x | test/StormTest.cpp | 217 | ||||
-rw-r--r-- | test/stormlib-test-001.txt | 3 |
11 files changed, 124 insertions, 282 deletions
diff --git a/Publish.bat b/Publish.bat deleted file mode 100644 index b5c71fc..0000000 --- a/Publish.bat +++ /dev/null @@ -1,25 +0,0 @@ -@echo off -rem This BAT file updates the ZIP file that is to be uploaded to web -rem Only use when both 32-bit and 64-bit are properly compiled - -set STORMLIB_NAME=stormlib-9.00 - -echo Creating %STORMLIB_NAME%.zip ... -cd \Ladik\Appdir -zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\doc\* -zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\src\* -zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\storm_dll\* -zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\StormLib.xcodeproj\* -zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\stormlib_dll\* -zip.exe -ur9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\test\* -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\CMakeLists.txt -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\makefile.* -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\Info.plist -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.bat -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.sln -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.vcproj -zip.exe -u9 ..\WWW\web\download\%STORMLIB_NAME%.zip StormLib\*.vcxproj -echo. - -echo Press any key to exit ... -pause >nul diff --git a/make-msvc.bat b/make-msvc.bat index 6e3782d..7d1052a 100644 --- a/make-msvc.bat +++ b/make-msvc.bat @@ -2,9 +2,10 @@ @echo off :: Save the values of INCLUDE, LIB and PATH +set PROJECT_DIR=%~dp0 set SAVE_INCLUDE=%INCLUDE% -set SAVE_LIB=%LIB% set SAVE_PATH=%PATH% +set SAVE_LIB=%LIB% set LIB_NAME=StormLib :: Determine where the program files are, both for 64-bit and 32-bit Windows @@ -59,13 +60,18 @@ call :BuildAndCopyLib %3 %SLN_TRG% %LIB_TRG% ReleaseAS call :BuildAndCopyLib %3 %SLN_TRG% %LIB_TRG% ReleaseUD call :BuildAndCopyLib %3 %SLN_TRG% %LIB_TRG% ReleaseUS -:: Restore environment variables to the old level +:: Restore environment variables to the old values set INCLUDE=%SAVE_INCLUDE% -set LIB=%SAVE_LIB% set PATH=%SAVE_PATH% +set LIB=%SAVE_LIB% + +:: Delete environment variables that are set by Visual Studio +set __VSCMD_PREINIT_PATH= +set EXTERNAL_INCLUDE= set VSINSTALLDIR= set VCINSTALLDIR= set DevEnvDir= +set LIBPATH= goto:eof ::----------------------------------------------------------------------------- @@ -73,7 +79,7 @@ goto:eof :: :: Parameters: :: -:: %1 Plain name of the .sln solution file ("StormLib_vs##.sln") +:: %1 Plain name of the .sln solution file :: %2 Target build platform ("Win32" or "x64") :: %3 Target directory for the library ("lib32", "lib32\vs2008", "lib64" or "lib64\vs2008") :: %4 Subvariant of the library ("DebugAD", "ReleaseUS", ...) @@ -86,4 +92,4 @@ if not exist ..\aaa goto:eof xcopy.exe /Y /D .\src\StormLib.h ..\aaa\inc >nul xcopy.exe /Y /D .\src\StormPort.h ..\aaa\inc >nul xcopy.exe /Y /D .\bin\StormLib\%2\%4\*.lib ..\aaa\%3 >nul -goto:eof + diff --git a/src/DllMain.rc b/src/DllMain.rc index 27f43e2..69b5cf0 100644 --- a/src/DllMain.rc +++ b/src/DllMain.rc @@ -16,10 +16,8 @@ // Neutral resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1250) -#endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // @@ -27,8 +25,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 9,22,0,3 - PRODUCTVERSION 9,22,0,3 + FILEVERSION 9,25,0,3 + PRODUCTVERSION 9,25,0,3 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,12 +43,12 @@ BEGIN BEGIN VALUE "Comments", "http://www.zezula.net/mpq.html" VALUE "FileDescription", "StormLib library for reading Blizzard MPQ archives" - VALUE "FileVersion", "9, 22, 0, 3\0" + VALUE "FileVersion", "9.25.0.3" VALUE "InternalName", "StormLib" - VALUE "LegalCopyright", "Copyright (c) 2014 - 2020 Ladislav Zezula" + VALUE "LegalCopyright", "Copyright (c) 2014 - 2023 Ladislav Zezula" VALUE "OriginalFilename", "StormLib.dll" VALUE "ProductName", "StormLib" - VALUE "ProductVersion", "9, 22, 0, 3\0" + VALUE "ProductVersion", "9.25.0.3" END END BLOCK "VarFileInfo" @@ -64,13 +62,11 @@ END ///////////////////////////////////////////////////////////////////////////// -// Czech resources +// Czech (Czech Republic) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) -#ifdef _WIN32 LANGUAGE LANG_CZECH, SUBLANG_DEFAULT #pragma code_page(1250) -#endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -78,26 +74,26 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT // TEXTINCLUDE // -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" END -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "resource.h\0" END #endif // APSTUDIO_INVOKED -#endif // Czech resources +#endif // Czech (Czech Republic) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/LibTomCrypt.c b/src/LibTomCrypt.c index 012f5e0..f77b604 100644 --- a/src/LibTomCrypt.c +++ b/src/LibTomCrypt.c @@ -8,6 +8,7 @@ #include "libtomcrypt/src/hashes/hash_memory.c" #include "libtomcrypt/src/hashes/md5.c" #include "libtomcrypt/src/hashes/sha1.c" +#include "libtomcrypt/src/hashes/sha256.c" #include "libtomcrypt/src/math/multi.c" #include "libtomcrypt/src/math/rand_prime.c" #include "libtomcrypt/src/misc/base64_decode.c" diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index b5b880e..664d4b0 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -244,8 +244,9 @@ void InitializeMpqCryptography() }
// Also register both MD5 and SHA1 hash algorithms
- register_hash(&md5_desc);
+ register_hash(&sha256_desc);
register_hash(&sha1_desc);
+ register_hash(&md5_desc);
// Use LibTomMath as support math library for LibTomCrypt
ltc_mp = ltm_desc;
diff --git a/src/SFileAddFile.cpp b/src/SFileAddFile.cpp index 5913424..2d14dda 100644 --- a/src/SFileAddFile.cpp +++ b/src/SFileAddFile.cpp @@ -246,6 +246,14 @@ static DWORD WriteDataToMpqFile( BSWAP_ARRAY32_UNSIGNED(pbToWrite, dwBytesInSector);
}
+ // Do not allow Warcraft III maps to go over 2GB.
+ // https://github.com/ladislav-zezula/StormLib/issues/306
+ if((ha->dwFlags & MPQ_FLAG_WAR3_MAP) && (ByteOffset + dwBytesInSector) > 0x7FFFFFFF)
+ {
+ dwErrCode = ERROR_DISK_FULL;
+ break;
+ }
+
// Write the file sector
if(!FileStream_Write(ha->pStream, &ByteOffset, pbToWrite, dwBytesInSector))
{
diff --git a/src/StormLib.h b/src/StormLib.h index 4d5992d..0bab24e 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -403,6 +403,10 @@ extern "C" { #define SHA1_DIGEST_SIZE 0x14 // 160 bits #endif +#ifndef SHA256_DIGEST_SIZE +#define SHA256_DIGEST_SIZE 0x20 // 256 bits +#endif + #ifndef LANG_NEUTRAL #define LANG_NEUTRAL 0x00 // Neutral locale #endif diff --git a/src/libtomcrypt/src/hashes/hash_memory.c b/src/libtomcrypt/src/hashes/hash_memory.c deleted file mode 100644 index 1daf0bf..0000000 --- a/src/libtomcrypt/src/hashes/hash_memory.c +++ /dev/null @@ -1,69 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include "../headers/tomcrypt.h" - -/** - @file hash_memory.c - Hash memory helper, Tom St Denis -*/ - -/** - Hash a block of memory and store the digest. - @param hash The index of the hash you wish to use - @param in The data you wish to hash - @param inlen The length of the data to hash (octets) - @param out [out] Where to store the digest - @param outlen [in/out] Max size and resulting size of the digest - @return CRYPT_OK if successful -*/ -int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) -{ - hash_state *md; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if ((err = hash_is_valid(hash)) != CRYPT_OK) { - return err; - } - - if (*outlen < hash_descriptor[hash].hashsize) { - *outlen = hash_descriptor[hash].hashsize; - return CRYPT_BUFFER_OVERFLOW; - } - - md = XMALLOC(sizeof(hash_state)); - if (md == NULL) { - return CRYPT_MEM; - } - - if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) { - goto LBL_ERR; - } - err = hash_descriptor[hash].done(md, out); - *outlen = hash_descriptor[hash].hashsize; -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(md, sizeof(hash_state)); -#endif - XFREE(md); - - return err; -} - -/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */ -/* $Revision: 1.6 $ */ -/* $Date: 2006/12/28 01:27:23 $ */ diff --git a/src/libtomcrypt/src/headers/tomcrypt_custom.h b/src/libtomcrypt/src/headers/tomcrypt_custom.h index 312a4c2..d53eef7 100644 --- a/src/libtomcrypt/src/headers/tomcrypt_custom.h +++ b/src/libtomcrypt/src/headers/tomcrypt_custom.h @@ -11,29 +11,29 @@ #define LTC_NO_ROLC #define LTC_SOURCE +#define LTC_SHA256 #define LTC_SHA1 #define LTC_MD5 #define LTC_DER -#define LTC_RC4 -#define USE_LTM #define LTM_DESC +#define USE_LTM /* macros for various libc functions you can change for embedded targets */ #ifndef XMALLOC - #ifdef malloc + #ifdef malloc #define LTC_NO_PROTOTYPES #endif #define XMALLOC LibTomMalloc #endif #ifndef XREALLOC - #ifdef realloc + #ifdef realloc #define LTC_NO_PROTOTYPES #endif #define XREALLOC LibTomRealloc #endif #ifndef XCALLOC - #ifdef calloc + #ifdef calloc #define LTC_NO_PROTOTYPES #endif #define XCALLOC LibTomCalloc @@ -58,7 +58,7 @@ #define XMEMCPY memcpy #endif #ifndef XMEMCMP - #ifdef memcmp + #ifdef memcmp #define LTC_NO_PROTOTYPES_MEMCMP #endif #define XMEMCMP memcmp @@ -91,19 +91,19 @@ #define LTC_BLOWFISH #define LTC_DES #define LTC_CAST5 - + #define LTC_NO_MODES #define LTC_ECB_MODE #define LTC_CBC_MODE #define LTC_CTR_MODE - + #define LTC_NO_HASHES #define LTC_SHA1 #define LTC_SHA512 #define LTC_SHA384 #define LTC_SHA256 #define LTC_SHA224 - + #define LTC_NO_MACS #define LTC_HMAC #define LTC_OMAC @@ -114,11 +114,11 @@ #define LTC_YARROW #define LTC_DEVRANDOM #define TRY_URANDOM_FIRST - + #define LTC_NO_PK #define LTC_MRSA #define LTC_MECC -#endif +#endif /* Use small code where possible */ /* #define LTC_SMALL_CODE */ @@ -194,7 +194,7 @@ #define LTC_LRW_MODE #ifndef LTC_NO_TABLES /* like GCM mode this will enable 16 8x128 tables [64KB] that make - * seeking very fast. + * seeking very fast. */ #define LRW_TABLES #endif @@ -205,7 +205,7 @@ #endif /* LTC_NO_MODES */ /* ---> One-Way Hash Functions <--- */ -#ifndef LTC_NO_HASHES +#ifndef LTC_NO_HASHES #define LTC_CHC_HASH #define LTC_WHIRLPOOL @@ -252,7 +252,7 @@ /* Use 64KiB tables */ #ifndef LTC_NO_TABLES - #define LTC_GCM_TABLES + #define LTC_GCM_TABLES #endif /* USE SSE2? requires GCC works on x86_32 and x86_64*/ @@ -319,7 +319,7 @@ #define LTC_MRSA /* Include Katja (a Rabin variant like RSA) */ -/* #define MKAT */ +/* #define MKAT */ /* Digital Signature Algorithm */ #define LTC_MDSA @@ -332,7 +332,7 @@ #if defined(TFM_LTC_DESC) && defined(LTC_MECC) #define LTC_MECC_ACCEL -#endif +#endif /* do we want fixed point ECC */ /* #define LTC_MECC_FP */ @@ -376,9 +376,9 @@ #ifdef LTC_MRSA #define LTC_PKCS_1 -#endif +#endif -#if defined(LTC_DER) && !defined(MPI) +#if defined(LTC_DER) && !defined(MPI) #error ASN.1 DER requires MPI functionality #endif diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 99138e4..c25ec84 100755 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -155,11 +155,6 @@ static TCHAR szMpqPatchDir[MAX_PATH] = {0}; #define SFLAG_SIGN_ARCHIVE 0x00000010 // Sign the archive
#define SFLAG_VERIFY_AFTER 0x00000020 // Verify the signature after modification
-// Flags for TestOpenArchive_AddFile
-#define TFLAG_REOPEN 0x00000001 // Reopen the archive
-#define TFLAG_HAS_LISTFILE 0x00000002 // The archive must have (listfile) after reopen
-#define TFLAG_HAS_ATTRIBUTES 0x00000004 // The archive must have (attributes) after reopen
-
static DWORD AddFlags[] =
{
// Compression Encryption Fixed key Single Unit Sector CRC
@@ -277,43 +272,6 @@ LPCTSTR GetRelativePath(LPCTSTR szFullPath) return _T("");
}
-static bool IsMpqExtension(LPCTSTR szFileName)
-{
- LPCTSTR szExtension = _tcsrchr(szFileName, '.');
-
- if(szExtension != NULL)
- {
- if(!_tcsicmp(szExtension, _T(".mpq")))
- return true;
- if(!_tcsicmp(szExtension, _T(".w3m")))
- return true;
- if(!_tcsicmp(szExtension, _T(".w3x")))
- return true;
- if(!_tcsicmp(szExtension, _T(".asi")))
- return true;
- if(!_tcsicmp(szExtension, _T(".mpqe")))
- return true;
- if(!_tcsicmp(szExtension, _T(".part")))
- return true;
- if(!_tcsicmp(szExtension, _T(".sv")))
- return true;
- if(!_tcsicmp(szExtension, _T(".s2ma")))
- return true;
- if(!_tcsicmp(szExtension, _T(".SC2Map")))
- return true;
- if(!_tcsicmp(szExtension, _T(".SC2Mod")))
- return true;
- if(!_tcsicmp(szExtension, _T(".SC2Replay")))
- return true;
- if(!_tcsicmp(szExtension, _T(".0"))) // .MPQ.0
- return true;
-// if(!_tcsicmp(szExtension, ".link"))
-// return true;
- }
-
- return false;
-}
-
// Converts binary array to string.
// The caller must ensure that the buffer has at least ((cbBinary * 2) + 1) characters
template <typename xchar>
@@ -418,33 +376,19 @@ static const XCHAR * GetShortPlainName(const XCHAR * szFileName) return szPlainName;
}
-static bool CopyStringAndVerifyConversion(
- LPCTSTR szFoundFile,
- TCHAR * szBufferT,
- char * szBufferA,
- size_t cchMaxChars)
-{
- // Convert the TCHAR name to ANSI name
- StringCopy(szBufferA, cchMaxChars, szFoundFile);
- StringCopy(szBufferT, cchMaxChars, szBufferA);
-
- // Compare both TCHAR strings
- return (_tcsicmp(szBufferT, szFoundFile) == 0) ? true : false;
-}
-
-static size_t ConvertSha1ToText(const unsigned char * sha1_digest, TCHAR * szSha1Text)
+static size_t ConvertSha256ToText(const unsigned char * sha_digest, LPTSTR szBuffer)
{
LPCSTR szTable = "0123456789abcdef";
- for(size_t i = 0; i < SHA1_DIGEST_SIZE; i++)
+ for(size_t i = 0; i < SHA256_DIGEST_SIZE; i++)
{
- *szSha1Text++ = szTable[(sha1_digest[0] >> 0x04)];
- *szSha1Text++ = szTable[(sha1_digest[0] & 0x0F)];
- sha1_digest++;
+ *szBuffer++ = szTable[(sha_digest[0] >> 0x04)];
+ *szBuffer++ = szTable[(sha_digest[0] & 0x0F)];
+ sha_digest++;
}
- *szSha1Text = 0;
- return (SHA1_DIGEST_SIZE * 2);
+ *szBuffer = 0;
+ return (SHA256_DIGEST_SIZE * 2);
}
static void CreateFullPathName(TCHAR * szBuffer, size_t cchBuffer, LPCTSTR szSubDir, LPCTSTR szNamePart1, LPCTSTR szNamePart2 = NULL)
@@ -537,12 +481,12 @@ static void CreateFullPathName(char * szBuffer, size_t cchBuffer, LPCTSTR szSubD }
#endif
-static DWORD CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * szFileSha1)
+static DWORD CalculateFileHash(TLogHelper * pLogger, LPCTSTR szFullPath, LPTSTR szFileHash)
{
TFileStream * pStream;
- unsigned char sha1_digest[SHA1_DIGEST_SIZE];
+ unsigned char file_hash[SHA256_DIGEST_SIZE];
LPCTSTR szShortPlainName = GetShortPlainName(szFullPath);
- hash_state sha1_state;
+ hash_state sha256_state;
ULONGLONG ByteOffset = 0;
ULONGLONG FileSize = 0;
LPCTSTR szHashingFormat = _T("Hashing %s " fmt_X_of_Y_a);
@@ -553,7 +497,7 @@ static DWORD CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * // Notify the user
pLogger->PrintProgress(_T("Hashing %s ..."), szShortPlainName);
- szFileSha1[0] = 0;
+ szFileHash[0] = 0;
// Open the file to be verified
pStream = FileStream_OpenFile(szFullPath, STREAM_FLAG_READ_ONLY);
@@ -566,10 +510,10 @@ static DWORD CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * pbFileBlock = STORM_ALLOC(BYTE, cbFileBlock);
if(pbFileBlock != NULL)
{
- // Initialize SHA1 calculation
- sha1_init(&sha1_state);
+ // Initialize SHA256 calculation
+ sha256_init(&sha256_state);
- // Calculate the SHA1 of the file
+ // Calculate the SHA256 of the file
while(ByteOffset < FileSize)
{
// Notify the user
@@ -583,19 +527,19 @@ static DWORD CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * break;
}
- // Add to SHA1
- sha1_process(&sha1_state, pbFileBlock, cbBytesToRead);
+ // Add to SHA256
+ sha256_process(&sha256_state, pbFileBlock, cbBytesToRead);
ByteOffset += cbBytesToRead;
}
// Notify the user
pLogger->PrintProgress(szHashingFormat, szShortPlainName, ByteOffset, FileSize);
- // Finalize SHA1
- sha1_done(&sha1_state, sha1_digest);
+ // Finalize SHA256
+ sha256_done(&sha256_state, file_hash);
- // Convert the SHA1 to ANSI text
- ConvertSha1ToText(sha1_digest, szFileSha1);
+ // Convert the SHA256 to ANSI text
+ ConvertSha256ToText(file_hash, szFileHash);
STORM_FREE(pbFileBlock);
}
@@ -603,7 +547,7 @@ static DWORD CalculateFileSha1(TLogHelper * pLogger, LPCTSTR szFullPath, TCHAR * }
// If we calculated something, return OK
- if(dwErrCode == ERROR_SUCCESS && szFileSha1[0] == 0)
+ if(dwErrCode == ERROR_SUCCESS && szFileHash[0] == 0)
dwErrCode = ERROR_CAN_NOT_COMPLETE;
return dwErrCode;
}
@@ -790,10 +734,11 @@ static DWORD ForEachFile_VerifyFileHash(LPCTSTR szFullPath, void * lpContext) {
TLogHelper * pLogger = (TLogHelper *)(lpContext);
PFILE_DATA pFileData;
- TCHAR * szExtension;
+ LPCTSTR szHashExtension = _T(".sha256");
+ LPTSTR szExtension;
TCHAR szShaFileName[MAX_PATH + 1];
- TCHAR szSha1Text[0x40];
- char szSha1TextA[0x40];
+ TCHAR szHashText[0x80];
+ char szHashTextA[0x80];
DWORD dwErrCode = ERROR_SUCCESS;
// Try to load the file with the SHA extension
@@ -802,25 +747,25 @@ static DWORD ForEachFile_VerifyFileHash(LPCTSTR szFullPath, void * lpContext) if(szExtension == NULL)
return ERROR_SUCCESS;
- // Skip .SHA and .TXT files
- if(!_tcsicmp(szExtension, _T(".sha")) || !_tcsicmp(szExtension, _T(".txt")))
+ // Skip .SHA256
+ if(!_tcsicmp(szExtension, szHashExtension))
return ERROR_SUCCESS;
// Load the local file to memory
- _tcscpy(szExtension, _T(".sha"));
+ _tcscpy(szExtension, szHashExtension);
pFileData = LoadLocalFile(pLogger, szShaFileName, false);
if(pFileData != NULL)
{
- // Calculate SHA1 of the entire file
- dwErrCode = CalculateFileSha1(pLogger, szFullPath, szSha1Text);
+ // Calculate SHA256 of the entire file
+ dwErrCode = CalculateFileHash(pLogger, szFullPath, szHashText);
if(dwErrCode == ERROR_SUCCESS)
{
// Compare with what we loaded from the file
- if(pFileData->dwFileSize >= (SHA1_DIGEST_SIZE * 2))
+ if(pFileData->dwFileSize >= (SHA256_DIGEST_SIZE * 2))
{
- // Compare the SHA1
- StringCopy(szSha1TextA, _countof(szSha1TextA), szSha1Text);
- if(_strnicmp(szSha1TextA, (char *)pFileData->FileData, (SHA1_DIGEST_SIZE * 2)))
+ // Compare the SHA256
+ StringCopy(szHashTextA, _countof(szHashTextA), szHashText);
+ if(_strnicmp(szHashTextA, (char *)pFileData->FileData, (SHA256_DIGEST_SIZE * 2)))
{
SetLastError(dwErrCode = ERROR_FILE_CORRUPT);
pLogger->PrintError(_T("File hash check failed: %s"), szFullPath);
@@ -1995,22 +1940,6 @@ static DWORD AddLocalFileToMpq( return ERROR_SUCCESS;
}
-static DWORD RenameMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szOldFileName, LPCSTR szNewFileName, DWORD dwExpectedError)
-{
- DWORD dwErrCode = ERROR_SUCCESS;
-
- // Notify the user
- pLogger->PrintProgress("Renaming %s to %s ...", szOldFileName, szNewFileName);
-
- // Perform the deletion
- if(!SFileRenameFile(hMpq, szOldFileName, szNewFileName))
- dwErrCode = GetLastError();
-
- if(dwErrCode != dwExpectedError)
- return pLogger->PrintErrorVa("Unexpected result from SFileRenameFile(%s -> %s)", szOldFileName, szNewFileName);
- return ERROR_SUCCESS;
-}
-
static DWORD RemoveMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileName, DWORD dwExpectedError)
{
DWORD dwErrCode = ERROR_SUCCESS;
@@ -2946,66 +2875,50 @@ static DWORD TestOpenArchive_CompactArchive(LPCTSTR szPlainName, LPCTSTR szCopyN return dwErrCode;
}
-static DWORD TestOpenArchive_AddFile(LPCTSTR szMpqName, DWORD dwFlags)
+static DWORD TestOpenArchive_AddFiles2GB(LPCTSTR szMpqName, DWORD /* dwFlags */)
{
- TLogHelper Logger("TestAddFileToMpq", szMpqName);
- PFILE_DATA pFileData = NULL;
- LPCTSTR szBackupMpq = (dwFlags & TFLAG_REOPEN) ? _T("StormLibTest_Reopened.mpq") : szMpqName;
- LPCSTR szFileName = "AddedFile001.txt";
- LPCSTR szFileData = "0123456789ABCDEF";
+ TLogHelper Logger("TestAddFileOver2GB", szMpqName);
+ LPCTSTR szCopyName = _T("size-overflow.w3m");
HANDLE hMpq = NULL;
- DWORD dwFileSize = (DWORD)strlen(szFileData);
DWORD dwErrCode = ERROR_SUCCESS;
+ TCHAR szFullPath[MAX_PATH];
+ bool bSucceeded = true;
// Copy the archive so we won't fuck up the original one
- dwErrCode = OpenExistingArchiveWithCopy(&Logger, szMpqName, szBackupMpq, &hMpq);
+ dwErrCode = OpenExistingArchiveWithCopy(&Logger, szMpqName, szCopyName, &hMpq);
if(dwErrCode == ERROR_SUCCESS)
{
- dwErrCode = AddFileToMpq(&Logger, hMpq, szFileName, szFileData, MPQ_FILE_IMPLODE, MPQ_COMPRESSION_PKWARE, ERROR_SUCCESS);
+ // Create both file names
+ CreateFullPathName(szFullPath, _countof(szFullPath), szDataFileDir, _T("new-file-big.mp4"));
+
+ // Add the file to MPQ. This must fail, because the map size
+ // will go over 2GB and StormLib marks the file malformed on subsequent open
+ dwErrCode = AddLocalFileToMpq(&Logger, hMpq, "added-extra-file.mp4", szFullPath);
+ if(dwErrCode != ERROR_DISK_FULL)
+ bSucceeded = false;
+
SFileCloseArchive(hMpq);
}
- // Now the file has been written and the MPQ has been saved.
- // We reopen the MPQ and check the state of (listfile) and (attributes)
- if((dwErrCode == ERROR_SUCCESS) && (dwFlags & TFLAG_REOPEN))
+ // Open the MPQ again
+ if(dwErrCode == ERROR_SUCCESS || dwErrCode == ERROR_DISK_FULL)
{
- if((dwErrCode = OpenExistingArchiveWithCopy(&Logger, NULL, szBackupMpq, &hMpq)) == ERROR_SUCCESS)
+ CreateFullPathName(szFullPath, _countof(szFullPath), NULL, szCopyName);
+ if((dwErrCode = OpenExistingArchive(&Logger, szFullPath, 0, &hMpq)) == ERROR_SUCCESS)
{
- // Verify presence of (listfile) and (attributes)
- CheckIfFileIsPresent(&Logger, hMpq, LISTFILE_NAME, (dwFlags & TFLAG_HAS_LISTFILE));
- CheckIfFileIsPresent(&Logger, hMpq, ATTRIBUTES_NAME, (dwFlags & TFLAG_HAS_ATTRIBUTES));
+ DWORD dwFlags = 0;
- // Try to open the file that we recently added
- dwErrCode = LoadMpqFile(Logger, hMpq, szFileName, 0, 0, &pFileData);
- if(dwErrCode == ERROR_SUCCESS)
- {
- // Verify if the file size matches
- if(pFileData->dwFileSize == dwFileSize)
- {
- // Verify if the file data match
- if(memcmp(pFileData->FileData, szFileData, dwFileSize))
- {
- Logger.PrintError("The data of the added file does not match");
- dwErrCode = ERROR_FILE_CORRUPT;
- }
- }
- else
- {
- Logger.PrintError("The size of the added file does not match");
- dwErrCode = ERROR_FILE_CORRUPT;
- }
+ SFileGetFileInfo(hMpq, SFileMpqFlags, &dwFlags, sizeof(dwFlags), NULL);
+ if(dwFlags & MPQ_FLAG_MALFORMED)
+ bSucceeded = false;
- // Delete the file data
- STORM_FREE(pFileData);
- }
- else
- {
- Logger.PrintError("Failed to open the file previously added");
- }
-
SFileCloseArchive(hMpq);
}
}
+
+ // Both tests must have succeeded
+ if(bSucceeded == false)
+ dwErrCode = ERROR_CAN_NOT_COMPLETE;
return dwErrCode;
}
@@ -4232,7 +4145,7 @@ static const TEST_INFO Test_ReplaceFile[] = //-----------------------------------------------------------------------------
// Main
-//#define TEST_COMMAND_LINE
+#define TEST_COMMAND_LINE
#define TEST_LOCAL_LISTFILE
#define TEST_STREAM_OPERATIONS
#define TEST_MASTER_MIRROR
@@ -4355,7 +4268,11 @@ int _tmain(int argc, TCHAR * argv[]) }
#endif
- // Verify SHA1 of each MPQ that we have in the list
+ // Add files so the archive will go over 2GB
+ if(dwErrCode == ERROR_SUCCESS)
+ dwErrCode = TestOpenArchive_AddFiles2GB(_T("MPQ_2002_v1_LargeMapFile.w3m"), 0);
+
+ // Verify SHA256 of each MPQ that we have in the list
if(dwErrCode == ERROR_SUCCESS)
dwErrCode = VerifyFileHashes(szMpqSubDir);
diff --git a/test/stormlib-test-001.txt b/test/stormlib-test-001.txt index 91af3c2..a80b2f5 100644 --- a/test/stormlib-test-001.txt +++ b/test/stormlib-test-001.txt @@ -119,6 +119,7 @@ Test_Signature (MPQ_1999_v1_WeakSigned1.mpq) succeeded. TestModifyMpq (MPQ_2014_v4_Base.StormReplay) succeeded. TestModifyMpq (MPQ_2022_v1_v4.329.w3x) succeeded. TestModifyMpq (MPQ_2023_v1_StarcraftMap.scm) succeeded. +TestAddFileOver2GB (MPQ_2002_v1_LargeMapFile.w3m) succeeded. TestVerifyHash succeeded. CreateEmptyMpq (StormLibTest_EmptyMpq_v2.mpq) succeeded. CreateEmptyMpq (StormLibTest_EmptyMpq_v4.mpq) succeeded. @@ -139,3 +140,5 @@ TestCompressions: Warning: CRC32 error on WaveFile_01.wav TestCompressions: Warning: CRC32 error on WaveFile_02.wav ListFilePos (StormLibTest_ListFilePos.mpq) succeeded. TestBigArchive (StormLibTest_BigArchive_v4.mpq) succeeded. + +E:\Ladik\Appdir\StormLib\bin\StormLib_test\x64\Release>
\ No newline at end of file |