aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SFileGetFileInfo.cpp14
-rw-r--r--src/SFileOpenFileEx.cpp13
-rw-r--r--src/StormLib.h2
-rwxr-xr-xtest/StormTest.cpp61
-rw-r--r--test/stormlib-test-001.txt3
5 files changed, 78 insertions, 15 deletions
diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp
index 7a8afe0..20f5e75 100644
--- a/src/SFileGetFileInfo.cpp
+++ b/src/SFileGetFileInfo.cpp
@@ -68,6 +68,10 @@ static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbDat
static bool GetInfo(void * pvFileInfo, DWORD cbFileInfo, const void * pvData, DWORD cbData, LPDWORD pcbLengthNeeded)
{
+ // Verify the input parameter
+ if(pvData == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
+
// Verify buffer pointer and buffer size
if(!GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded))
return false;
@@ -81,6 +85,10 @@ static bool GetInfo_Allocated(void * pvFileInfo, DWORD cbFileInfo, void * pvData
{
bool bResult;
+ // Verify the input parameter
+ if(pvData == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
+
// Verify buffer pointer and buffer size
if((bResult = GetInfo_BufferCheck(pvFileInfo, cbFileInfo, cbData, pcbLengthNeeded)) != false)
memcpy(pvFileInfo, pvData, cbData);
@@ -401,15 +409,21 @@ bool WINAPI SFileGetFileInfo(
return GetInfo(pvFileInfo, cbFileInfo, &hf->dwHashIndex, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoNameHash1:
+ if(hf->pHashEntry == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName1, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoNameHash2:
+ if(hf->pHashEntry == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
return GetInfo(pvFileInfo, cbFileInfo, &hf->pHashEntry->dwName2, sizeof(DWORD), pcbLengthNeeded);
case SFileInfoNameHash3:
return GetInfo(pvFileInfo, cbFileInfo, &pFileEntry->FileNameHash, sizeof(ULONGLONG), pcbLengthNeeded);
case SFileInfoLocale:
+ if(hf->pHashEntry == NULL)
+ return GetInfo_ReturnError(ERROR_INVALID_PARAMETER);
dwInt32Value = SFILE_MAKE_LCID(hf->pHashEntry->Locale, hf->pHashEntry->Platform);
return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded);
diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp
index b5829b4..d26e01e 100644
--- a/src/SFileOpenFileEx.cpp
+++ b/src/SFileOpenFileEx.cpp
@@ -20,7 +20,6 @@ static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex)
{
TMPQHash * pHashTableEnd;
TMPQHash * pHash;
- DWORD dwFirstIndex = HASH_ENTRY_FREE;
// Should only be called if the archive has hash table
assert(ha->pHashTable != NULL);
@@ -32,15 +31,15 @@ static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex)
{
if(MPQ_BLOCK_INDEX(pHash) == dwFileIndex)
{
- // Duplicate hash entry found
- if(dwFirstIndex != HASH_ENTRY_FREE)
- return HASH_ENTRY_FREE;
- dwFirstIndex = (DWORD)(pHash - ha->pHashTable);
+ // Find the first hash entry that points to it.
+ // If there are multiple hash entries that point
+ // to the same file, only the first one is returned.
+ return (DWORD)(pHash - ha->pHashTable);
}
}
- // Return the hash table entry index
- return dwFirstIndex;
+ // No item was found
+ return HASH_ENTRY_FREE;
}
static const char * GetPatchFileName(TMPQArchive * ha, const char * szFileName, char * szBuffer)
diff --git a/src/StormLib.h b/src/StormLib.h
index 901f943..b78f7ef 100644
--- a/src/StormLib.h
+++ b/src/StormLib.h
@@ -477,6 +477,8 @@ typedef enum _SFileInfoClass
SFileInfoEncryptionKey, // File encryption key
SFileInfoEncryptionKeyRaw, // Unfixed value of the file key
SFileInfoCRC32, // CRC32 of the file
+
+ SFileInfoInvalid = 0xFFF, // Invalid file info class
} SFileInfoClass;
//-----------------------------------------------------------------------------
diff --git a/test/StormTest.cpp b/test/StormTest.cpp
index f4498b5..4e13b9f 100755
--- a/test/StormTest.cpp
+++ b/test/StormTest.cpp
@@ -55,6 +55,7 @@ typedef enum _EXTRA_TYPE
ListFile,
TwoFiles,
PatchList,
+ HashValues,
} EXTRA_TYPE, *PEXTRA_TYPE;
typedef struct _FILE_DATA
@@ -87,6 +88,14 @@ typedef struct _TEST_EXTRA_PATCHES
DWORD dwPatchCount; // Number of patches
} TEST_EXTRA_PATCHES, *PTEST_EXTRA_PATCHES;
+typedef struct _TEST_EXTRA_HASHVALS
+{
+ EXTRA_TYPE Type; // Must be PatchList
+ LPCSTR szFileName; // File name
+ DWORD dwHash1; // Hash A of the file name
+ DWORD dwHash2; // Hash B of the file name
+} TEST_EXTRA_HASHVALS, *PTEST_EXTRA_HASHVALS;
+
typedef struct _TEST_INFO
{
LPCTSTR szName1; // MPQ name
@@ -2422,6 +2431,29 @@ static DWORD TestOpenArchive_Extra_Patches(TLogHelper & Logger, HANDLE hMpq, PTE
return dwErrCode;
}
+static DWORD TestOpenArchive_Extra_HashValues(TLogHelper & Logger, HANDLE hMpq, PTEST_EXTRA_HASHVALS pExtra)
+{
+ HANDLE hFile = NULL;
+ DWORD dwErrCode = ERROR_SUCCESS;
+ DWORD dwHash1 = 0;
+ DWORD dwHash2 = 0;
+ DWORD cbHash = 0;
+
+ if(SFileOpenFileEx(hMpq, pExtra->szFileName, 0, &hFile))
+ {
+ SFileGetFileInfo(hFile, SFileInfoNameHash1, &dwHash1, sizeof(dwHash1), &cbHash);
+ assert(cbHash == sizeof(DWORD));
+
+ SFileGetFileInfo(hFile, SFileInfoNameHash2, &dwHash2, sizeof(dwHash2), &cbHash);
+ assert(cbHash == sizeof(DWORD));
+
+ if(dwHash1 != pExtra->dwHash1 || dwHash2 != pExtra->dwHash2)
+ dwErrCode = Logger.PrintError("Name hash values mismatch on %s", pExtra->szFileName);
+ SFileCloseFile(hFile);
+ }
+ return dwErrCode;
+}
+
static DWORD TestOpenArchive_ExtraType(TLogHelper & Logger, HANDLE hMpq, DWORD dwSearchFlags, const void * pExtra)
{
switch(GetExtraType(pExtra))
@@ -2435,6 +2467,9 @@ static DWORD TestOpenArchive_ExtraType(TLogHelper & Logger, HANDLE hMpq, DWORD d
case PatchList:
return TestOpenArchive_Extra_Patches(Logger, hMpq, (PTEST_EXTRA_PATCHES)(pExtra));
+ case HashValues:
+ return TestOpenArchive_Extra_HashValues(Logger, hMpq, (PTEST_EXTRA_HASHVALS)(pExtra));
+
default:
return ERROR_SUCCESS;
}
@@ -2484,8 +2519,8 @@ static DWORD TestOpenArchive_GetFileInfo(TLogHelper & Logger, HANDLE hMpq, DWORD
SFileGetFileInfo(hMpq, SFileMpqHeader, &Header, sizeof(TMPQHeader), NULL);
// Test on invalid archive/file handle
- TestGetFileInfo(&Logger, NULL, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
- TestGetFileInfo(&Logger, NULL, (SFileInfoClass)0xFFF, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
+ TestGetFileInfo(&Logger, NULL, SFileMpqBetHeader, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
+ TestGetFileInfo(&Logger, NULL, SFileInfoInvalid, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
TestGetFileInfo(&Logger, NULL, SFileInfoNameHash1, NULL, 0, NULL, false, ERROR_INVALID_HANDLE);
// Valid handle but all parameters NULL
@@ -2524,6 +2559,14 @@ static DWORD TestOpenArchive_GetFileInfo(TLogHelper & Logger, HANDLE hMpq, DWORD
TestGetFileInfo(&Logger, hFile, SFileInfoFileTime, DataBuff, sizeof(DataBuff), &cbLength, true, ERROR_SUCCESS);
SFileCloseFile(hFile);
}
+
+ // This file is in MPQ_2023_v1_Lusin2Rpg1.28.w3x
+ if(SFileOpenFileEx(hMpq, "File00002875.blp", 0, &hFile))
+ {
+ TestGetFileInfo(&Logger, hFile, SFileInfoNameHash1, DataBuff, sizeof(DWORD), NULL, true, ERROR_SUCCESS);
+ TestGetFileInfo(&Logger, hFile, SFileInfoNameHash2, DataBuff, sizeof(DWORD), NULL, true, ERROR_SUCCESS);
+ SFileCloseFile(hFile);
+ }
}
return ERROR_SUCCESS;
}
@@ -3791,18 +3834,22 @@ static DWORD TestReplaceFile(LPCTSTR szMpqPlainName, LPCTSTR szFilePlainName, LP
static void Test_PlayingSpace()
{
-/*
+
// Check opening of a MPQ
- LPCTSTR szArchiveName = _T("e:\\GreenTD.w3x");
+ LPCTSTR szArchiveName = _T("e:\\MPQ_2023_v1_Lusin2Rpg1.28.w3x");
LPBYTE pbBuffer = NULL;
HANDLE hFile = NULL;
HANDLE hMpq = NULL;
DWORD dwFileSize;
+ DWORD dwInt32;
if(SFileOpenArchive(szArchiveName, 0, 0, &hMpq))
{
- if(SFileOpenFileEx(hMpq, "File00000160.xxx", 0, &hFile))
+ if(SFileOpenFileEx(hMpq, "File00002875.blp", 0, &hFile))
{
+ SFileGetFileInfo(hFile, SFileInfoNameHash1, &dwInt32, sizeof(dwInt32), NULL);
+ SFileGetFileInfo(hFile, SFileInfoNameHash2, &dwInt32, sizeof(dwInt32), NULL);
+
if((dwFileSize = SFileGetFileSize(hFile, NULL)) != NULL)
{
if((pbBuffer = STORM_ALLOC(BYTE, dwFileSize)) != NULL)
@@ -3817,7 +3864,6 @@ static void Test_PlayingSpace()
}
SFileCloseArchive(hMpq);
}
-*/
}
//-----------------------------------------------------------------------------
@@ -3838,6 +3884,8 @@ static const TEST_EXTRA_TWOFILES TwoFilesD2 = {TwoFiles, "waitingroombkgd.dc6"};
static const TEST_EXTRA_TWOFILES TwoFilesW3M = {TwoFiles, "file00000002.blp"};
static const TEST_EXTRA_TWOFILES TwoFilesW3X = {TwoFiles, "BlueCrystal.mdx"};
+static const TEST_EXTRA_HASHVALS HashVals = {HashValues, "File00002875.blp", 0xb93b0e63, 0xe50dfdd8};
+
static const TEST_EXTRA_PATCHES PatchSC1 =
{
PatchList,
@@ -4066,6 +4114,7 @@ static const TEST_INFO Test_OpenMpqs[] =
{_T("MPQ_2021_v1_CantExtractCHK.scx"), NULL, "055fd548a789c910d9dd37472ecc1e66", 28},
{_T("MPQ_2022_v1_Sniper.scx"), NULL, "2e955271b70b79344ad85b698f6ce9d8", 64}, // Multiple items in hash table for staredit\scenario.chk (locale=0, platform=0)
{_T("MPQ_2022_v1_OcOc_Bound_2.scx"), NULL, "25cad16a2fb4e883767a1f512fc1dce7", 16},
+ {_T("MPQ_2023_v1_Lusin2Rpg1.28.w3x"), NULL, "9c21352f06cf763fcf05e8a2691e6194", 10305, &HashVals},
// ASI plugins
{_T("MPQ_2020_v1_HS0.1.asi"), NULL, "50cba7460a6e6d270804fb9776a7ec4f", 6022},
diff --git a/test/stormlib-test-001.txt b/test/stormlib-test-001.txt
index a80b2f5..7b780cf 100644
--- a/test/stormlib-test-001.txt
+++ b/test/stormlib-test-001.txt
@@ -75,6 +75,7 @@ TestReadingMpq (MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x) succeeded.
TestReadingMpq (MPQ_2021_v1_CantExtractCHK.scx) succeeded.
TestReadingMpq (MPQ_2022_v1_Sniper.scx) succeeded.
TestReadingMpq (MPQ_2022_v1_OcOc_Bound_2.scx) succeeded.
+TestReadingMpq (MPQ_2023_v1_Lusin2Rpg1.28.w3x) succeeded.
TestReadingMpq (MPQ_2020_v1_HS0.1.asi) succeeded.
TestReadingMpq (MPQ_2022_v1_hs0.8.asi) succeeded.
TestReadingMpq (MPQ_2022_v1_MoeMoeMod.asi) succeeded.
@@ -140,5 +141,3 @@ 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