From d1bf5e1c71af432ccc24371a3611dc33edb7361f Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Wed, 4 Dec 2024 09:16:28 +0100 Subject: Changed behavior of patched files with MPQ_FLAG_DELETE_MARKER --- src/SBaseCommon.cpp | 26 +++++++++++++++++++++++++ src/SFileFindFile.cpp | 2 ++ src/SFileOpenFileEx.cpp | 8 ++++++++ src/StormCommon.h | 8 ++++++++ src/StormLib.h | 7 ++++--- test/StormTest.cpp | 51 +++++++++++++++++++++++++++++++++++++++++-------- test/TLogHelper.cpp | 1 + 7 files changed, 92 insertions(+), 11 deletions(-) diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 3f95ded..7f2aa8c 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -1968,3 +1968,29 @@ void ConvertTMPQHeader(void *header, uint16_t version) } #endif // STORMLIB_LITTLE_ENDIAN + +//----------------------------------------------------------------------------- +// Debug support + +/* +#include + +#if defined(STORMLIB_WINDOWS) && defined(_DEBUG) +void SFileLog(const char * format, ...) +{ + va_list argList; + char * szBuffer; + size_t nLength = 0x1000; + + if((szBuffer = STORM_ALLOC(char, 0x1000)) != NULL) + { + va_start(argList, format); + StringCchVPrintfA(szBuffer, nLength, format, argList); + va_end(argList); + + OutputDebugStringA(szBuffer); + STORM_FREE(szBuffer); + } +} +#endif +*/ \ No newline at end of file diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp index b741e5f..8f4849f 100644 --- a/src/SFileFindFile.cpp +++ b/src/SFileFindFile.cpp @@ -352,7 +352,9 @@ static DWORD DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData) dwErrCode = (ha->pHashTable != NULL) ? DoMPQSearch_HashTable(hs, lpFindFileData, ha) : DoMPQSearch_FileTable(hs, lpFindFileData, ha); if(dwErrCode == ERROR_SUCCESS) + { return dwErrCode; + } // If there is no more patches in the chain, stop it. // This also keeps hs->ha non-NULL, which is required diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp index 90c7fab..2954669 100644 --- a/src/SFileOpenFileEx.cpp +++ b/src/SFileOpenFileEx.cpp @@ -155,6 +155,14 @@ bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile) hf = hfPatch; } } + + // If the opened file has the delete marker, we don't open the file + if(hfBase && hf && hf->pFileEntry->dwFlags & MPQ_FILE_DELETE_MARKER) + { + SFileCloseFile((HANDLE)(hfBase)); + SetLastError(ERROR_FILE_DELETED); + hfBase = NULL; + } } } else diff --git a/src/StormCommon.h b/src/StormCommon.h index 1e67a27..bf82039 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -513,5 +513,13 @@ void DumpFileTable(TFileEntry * pFileTable, DWORD dwFileTableSize); #endif +/* +#ifdef _DEBUG +void SFileLog(const char * format, ...); +#else +inline void SFileLog(...) {} +#endif +*/ + #endif // __STORMCOMMON_H__ diff --git a/src/StormLib.h b/src/StormLib.h index bf884c5..c4542d9 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -102,11 +102,11 @@ extern "C" { // Z - S for static-linked CRT library, D for multithreaded DLL CRT library // -#if defined(__STORMLIB_SELF__) && !defined(STORMLIB_NO_AUTO_LINK) -#define STORMLIB_NO_AUTO_LINK // Define this if you don't want to link using pragmas when using msvc +#if defined(__STORMLIB_SELF__) && !defined(__STORMLIB_NO_STATIC_LINK__) +#define __STORMLIB_NO_STATIC_LINK__ // Define this if you don't want to link using pragmas when using msvc #endif -#if defined(_MSC_VER) && !defined(STORMLIB_NO_AUTO_LINK) +#if defined(_MSC_VER) && !defined(__STORMLIB_NO_STATIC_LINK__) #ifndef WDK_BUILD #ifdef _DEBUG // DEBUG VERSIONS #ifndef _UNICODE @@ -163,6 +163,7 @@ extern "C" { #define ERROR_UNKNOWN_FILE_NAMES 10007 // A name of at least one file is unknown #define ERROR_CANT_FIND_PATCH_PREFIX 10008 // StormLib was unable to find patch prefix for the patches #define ERROR_FAKE_MPQ_HEADER 10009 // The header at this position is fake header +#define ERROR_FILE_DELETED 10010 // The file is present but contains delete marker // Values for SFileCreateArchive #define HASH_TABLE_SIZE_MIN 0x00000004 // Verified: If there is 1 file, hash table size is 4 diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 7cd885d..7a4459c 100755 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -106,7 +106,7 @@ typedef struct _TEST_EXTRA_HASHVAL typedef struct _TEST_EXTRA_HASHVALS { - EXTRA_TYPE Type; // Must be PatchList + EXTRA_TYPE Type; // Must be HashValues TEST_EXTRA_HASHVAL Items[2]; } TEST_EXTRA_HASHVALS, *PTEST_EXTRA_HASHVALS; @@ -573,16 +573,16 @@ static void CreateFullPathName(char * szBuffer, size_t cchBuffer, LPCTSTR szSubD static DWORD CalculateFileHash(TLogHelper * pLogger, LPCTSTR szFullPath, LPTSTR szFileHash) { TFileStream * pStream; - unsigned char file_hash[SHA256_DIGEST_SIZE]; - LPCTSTR szShortPlainName = GetShortPlainName(szFullPath); hash_state sha256_state; ULONGLONG ByteOffset = 0; ULONGLONG FileSize = 0; - LPCSTR szHashingFormat = "Hashing %s " fmt_X_of_Y_a; + LPCTSTR szShortPlainName = GetShortPlainName(szFullPath); + LPCTSTR szHashingFormat = _T("Hashing %s ") fmt_X_of_Y_t; LPBYTE pbFileBlock; DWORD cbBytesToRead; DWORD cbFileBlock = 0x100000; DWORD dwErrCode = ERROR_SUCCESS; + BYTE file_hash[SHA256_DIGEST_SIZE]; // Notify the user pLogger->PrintProgress(_T("Hashing %s ..."), szShortPlainName); @@ -1038,7 +1038,10 @@ static DWORD GetFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileN } else { - pLogger->PrintError("Open failed: %s", szFileName); + if(GetLastError() != ERROR_FILE_DELETED) + { + pLogger->PrintError("Open failed: %s", szFileName); + } } return nPatchCount; @@ -1049,7 +1052,7 @@ static DWORD VerifyFilePatchCount(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFi DWORD dwPatchCount = 0; // Retrieve the patch count - pLogger->PrintProgress(_T("Verifying patch count for %s ..."), szFileName); + pLogger->PrintProgress("Verifying patch count for %s ...", szFileName); dwPatchCount = GetFilePatchCount(pLogger, hMpq, szFileName); // Check if there are any patches at all @@ -1442,6 +1445,7 @@ static DWORD LoadMpqFile(TLogHelper & Logger, HANDLE hMpq, LPCSTR szFileName, LC // Make sure that we open the proper locale file SFileSetLocale(lcFileLocale); + *ppFileData = NULL; // Open the file from MPQ if(SFileOpenFileEx(hMpq, szFileName, 0, &hFile)) @@ -1510,7 +1514,7 @@ static DWORD LoadMpqFile(TLogHelper & Logger, HANDLE hMpq, LPCSTR szFileName, LC } else { - if((dwSearchFlags & SEARCH_FLAG_IGNORE_ERRORS) == 0) + if((dwSearchFlags & SEARCH_FLAG_IGNORE_ERRORS) == 0 && GetLastError() != ERROR_FILE_DELETED) { dwErrCode = Logger.PrintError("Open failed: %s", szFileName); } @@ -3859,7 +3863,28 @@ static DWORD TestUtf8Conversions(const BYTE * szTestString, const TCHAR * szList } static void Test_PlayingSpace() -{} +{ +/* + HANDLE hFile = NULL; + HANDLE hMpq = NULL; + + if(SFileOpenArchive(_T("\\Ladik\\Incoming\\texture.MPQ"), 0, STREAM_FLAG_READ_ONLY, &hMpq)) + { + if(SFileOpenPatchArchive(hMpq, _T("\\Ladik\\Incoming\\patch.mpq"), NULL, 0)) + { + if(SFileOpenFileEx(hMpq, "Creature\\GnomeSpidertank\\FlameLickSmallBlue.blp", 0, &hFile)) + { + DWORD dwBytesRead = 0; + BYTE Buffer[1024]; + + SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL); + SFileCloseFile(hFile); + } + } + SFileCloseArchive(hMpq); + } +*/ +} //----------------------------------------------------------------------------- // Tables @@ -3946,6 +3971,15 @@ static const TEST_EXTRA_PATCHES PatchSC1 = 0 }; +static const TEST_EXTRA_PATCHES PatchBETA = +{ + PatchList, + _T("wow-08-beta-patch.mpq\0"), + "Creature\\GnomeSpidertank\\FlameLickSmallBlue.blp", + 0 +}; + + static const TEST_EXTRA_PATCHES Patch13286 = { PatchList, @@ -4201,6 +4235,7 @@ static const TEST_INFO1 Test_OpenMpqs[] = // Patched MPQs {_T("MPQ_1998_v1_StarCraft.mpq"), NULL, "5ecef2f41c5fd44c264e269416de9495", 1943, &PatchSC1}, // Patched MPQ from StarCraft I + {_T("MPQ_2005_v1_texture.MPQ"), NULL, "f95f44bfd8e6dde30508bfec2d4cb842", 45533, &PatchBETA}, // WoW BETA: Patched "texture.MPQ" {_T("MPQ_2012_v4_OldWorld.MPQ"), NULL, "07643ec62864b4dd4fc8f8a6a16ce006", 71439, &Patch13286}, // WoW 13286: Patched "OldWorld.MPQ" {_T("MPQ_2013_v4_world.MPQ"), NULL, "af9baeceab20139bbf94d03f99170ae0", 48930, &Patch15050}, // WoW 15050: Patched "world.MPQ" {_T("MPQ_2013_v4_locale-enGB.MPQ"), NULL, "d39e743aaf6dad51d643d65e6e564804", 14349, &Patch16965}, // WoW 16965: Patched "locale-enGB.MPQ" diff --git a/test/TLogHelper.cpp b/test/TLogHelper.cpp index c0e5e14..baa5327 100644 --- a/test/TLogHelper.cpp +++ b/test/TLogHelper.cpp @@ -29,6 +29,7 @@ #endif #define fmt_X_of_Y_a "(" fmt_I64u_a " of " fmt_I64u_a ")" +#define fmt_X_of_Y_t _T(fmt_X_of_Y_a) #ifdef __CASCLIB_SELF__ #define TEST_MIN CASCLIB_MIN -- cgit v1.2.3