aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Publish.bat25
-rw-r--r--make-msvc.bat16
-rw-r--r--src/DllMain.rc24
-rw-r--r--src/LibTomCrypt.c1
-rw-r--r--src/SBaseCommon.cpp3
-rw-r--r--src/SFileAddFile.cpp8
-rw-r--r--src/StormLib.h4
-rw-r--r--src/libtomcrypt/src/hashes/hash_memory.c69
-rw-r--r--src/libtomcrypt/src/headers/tomcrypt_custom.h36
-rwxr-xr-xtest/StormTest.cpp217
-rw-r--r--test/stormlib-test-001.txt3
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