diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-05-07 14:39:40 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-05-07 14:39:40 +0200 |
commit | ea812fec1153280b94d2fff8bdefd678e86bddeb (patch) | |
tree | cd7d75fc98ab6cc2c975fe4db9be67ccb87f40c1 /dep/CascLib/src/CascIndexFiles.cpp | |
parent | dfdabdb97bdd776da4add3cd4f19cf5793160abf (diff) |
Dep/CascLib: Update to ladislav-zezula/CascLib@0a05c59eb8a3eab1bc5471f43934cd5f992f0aca
Diffstat (limited to 'dep/CascLib/src/CascIndexFiles.cpp')
-rw-r--r-- | dep/CascLib/src/CascIndexFiles.cpp | 84 |
1 files changed, 67 insertions, 17 deletions
diff --git a/dep/CascLib/src/CascIndexFiles.cpp b/dep/CascLib/src/CascIndexFiles.cpp index eddbdb67b0d..bfcee15330b 100644 --- a/dep/CascLib/src/CascIndexFiles.cpp +++ b/dep/CascLib/src/CascIndexFiles.cpp @@ -28,7 +28,7 @@ typedef bool (*EKEY_ENTRY_CALLBACK)(TCascStorage * hs, CASC_INDEX_HEADER & InHea // Local functions // "data.iXY" -static bool IsIndexFileName_V1(const TCHAR * szFileName) +static bool IsIndexFileName_V1(LPCTSTR szFileName) { // Check if the name looks like a valid index file return (_tcslen(szFileName) == 8 && @@ -36,7 +36,7 @@ static bool IsIndexFileName_V1(const TCHAR * szFileName) _tcsspn(szFileName + 6, szAllowedHexChars) == 2); } -static bool IsIndexFileName_V2(const TCHAR * szFileName) +static bool IsIndexFileName_V2(LPCTSTR szFileName) { // Check if the name looks like a valid index file return (_tcslen(szFileName) == 14 && @@ -116,7 +116,7 @@ static bool IndexDirectory_OnFileFound( return true; } -static TCHAR * CreateIndexFileName(TCascStorage * hs, DWORD IndexValue, DWORD IndexVersion) +static LPTSTR CreateIndexFileName(TCascStorage * hs, DWORD IndexValue, DWORD IndexVersion) { TCHAR szPlainName[0x40]; @@ -167,6 +167,7 @@ static LPBYTE CaptureGuardedBlock2(LPBYTE pbFileData, LPBYTE pbFileEnd, size_t E PFILE_INDEX_GUARDED_BLOCK pBlock = (PFILE_INDEX_GUARDED_BLOCK)pbFileData; LPBYTE pbEntryPtr; size_t EntryCount; + unsigned int HashBlizzGet = 0; unsigned int HashHigh = 0; unsigned int HashLow = 0; @@ -177,7 +178,10 @@ static LPBYTE CaptureGuardedBlock2(LPBYTE pbFileData, LPBYTE pbFileEnd, size_t E if (pBlock->BlockSize == 0 || (pbFileData + sizeof(FILE_INDEX_GUARDED_BLOCK) + pBlock->BlockSize) > pbFileEnd) return NULL; - // Compute the hash entry-by-entry + // + // Verify the hash from the Blizzard Downloader + // + pbEntryPtr = pbFileData + sizeof(FILE_INDEX_GUARDED_BLOCK); EntryCount = pBlock->BlockSize / EntryLength; for (size_t i = 0; i < EntryCount; i++) @@ -187,13 +191,39 @@ static LPBYTE CaptureGuardedBlock2(LPBYTE pbFileData, LPBYTE pbFileEnd, size_t E } // Verify hash - if (HashHigh != pBlock->BlockHash) - return NULL; + if (HashHigh == pBlock->BlockHash) + { + // Give the output + if (PtrBlockSize != NULL) + PtrBlockSize[0] = pBlock->BlockSize; + return (LPBYTE)(pBlock + 1); + } - // Give the output - if (PtrBlockSize != NULL) - PtrBlockSize[0] = pBlock->BlockSize; - return (LPBYTE)(pBlock + 1); + // + // Verify the hash from the Blizzget tool, which calculates the hash differently + // https://github.com/d07RiV/blizzget/blob/master/src/ngdp.cpp + // Function void DataStorage::writeIndex() + // + + pbEntryPtr = pbFileData + sizeof(FILE_INDEX_GUARDED_BLOCK); + EntryCount = pBlock->BlockSize / EntryLength; + for (size_t i = 0; i < EntryCount; i++) + { + HashBlizzGet = hashlittle(pbEntryPtr, EntryLength, HashBlizzGet); + pbEntryPtr += EntryLength; + } + + // Verify hash + if (HashBlizzGet == pBlock->BlockHash) + { + // Give the output + if (PtrBlockSize != NULL) + PtrBlockSize[0] = pBlock->BlockSize; + return (LPBYTE)(pBlock + 1); + } + + // Hash mismatch + return NULL; } // Third method of checking a guarded block; There is 32-bit hash, followed by EKey entry @@ -286,8 +316,11 @@ static DWORD LoadIndexItems(TCascStorage * hs, CASC_INDEX_HEADER & InHeader, EKE while((pbEKeyEntry + EntryLength) <= pbEKeyEnd) { - // DOWNLOAD in HOTS - //BREAK_ON_XKEY3(EKeyEntry.EKey, 0x09, 0xF3, 0xCD); + // ENCODING, DOWNLOAD, ROOT in Warcraft III Reforged build 14481 + BREAK_ON_XKEY3(pbEKeyEntry, 0xcd, 0x3b, 0xd8); + BREAK_ON_XKEY3(pbEKeyEntry, 0xdb, 0xfa, 0x35); + BREAK_ON_XKEY3(pbEKeyEntry, 0x5c, 0xe8, 0x48); + if(!PfnEKeyEntry(hs, InHeader, pbEKeyEntry)) return ERROR_INDEX_PARSING_DONE; @@ -487,17 +520,17 @@ static bool InsertEncodingEKeyToMap(TCascStorage * hs, CASC_INDEX_HEADER &, LPBY return true; } -static DWORD ProcessLocalIndexFiles(TCascStorage * hs, EKEY_ENTRY_CALLBACK PfnEKeyEntry) +static DWORD ProcessLocalIndexFiles(TCascStorage * hs, EKEY_ENTRY_CALLBACK PfnEKeyEntry, DWORD dwIndexCount) { DWORD dwErrCode = ERROR_SUCCESS; // Load each index file - for(DWORD i = 0; i < CASC_INDEX_COUNT; i++) + for(DWORD i = 0; i < dwIndexCount; i++) { CASC_INDEX & IndexFile = hs->IndexFiles[i]; // Inform the user about what we are doing - if(InvokeProgressCallback(hs, "Loading index files", NULL, i, CASC_INDEX_COUNT)) + if(InvokeProgressCallback(hs, "Loading index files", NULL, i, dwIndexCount)) { dwErrCode = ERROR_CANCELLED; break; @@ -520,6 +553,7 @@ static DWORD ProcessLocalIndexFiles(TCascStorage * hs, EKEY_ENTRY_CALLBACK PfnEK static DWORD LoadLocalIndexFiles(TCascStorage * hs) { ULONGLONG TotalSize = 0; + DWORD dwIndexCount = 0; DWORD dwErrCode; // Inform the user about what we are doing @@ -529,6 +563,10 @@ static DWORD LoadLocalIndexFiles(TCascStorage * hs) // Perform the directory scan if((dwErrCode = ScanIndexDirectory(hs->szIndexPath, IndexDirectory_OnFileFound, hs)) == ERROR_SUCCESS) { + // If no index file was found, we cannot load anything + if(hs->szIndexFormat == NULL) + return ERROR_FILE_NOT_FOUND; + // Load each index file for(DWORD i = 0; i < CASC_INDEX_COUNT; i++) { @@ -541,16 +579,28 @@ static DWORD LoadLocalIndexFiles(TCascStorage * hs) // WoW6 actually reads THE ENTIRE file to memory. Verified on Mac build (x64). if((IndexFile.pbFileData = LoadFileToMemory(IndexFile.szFileName, &cbFileData)) == NULL) - return ERROR_NOT_ENOUGH_MEMORY; + { + // Storages downloaded by Blizzget tool don't have all index files present + if((dwErrCode = GetLastError()) == ERROR_FILE_NOT_FOUND) + { + dwErrCode = ERROR_SUCCESS; + break; + } + + return dwErrCode; + } + + // Add to the total size of the index files IndexFile.cbFileData = cbFileData; TotalSize += cbFileData; + dwIndexCount++; } // Build the map of EKey -> IndexEKeyEntry dwErrCode = hs->IndexEKeyMap.Create((size_t)(TotalSize / sizeof(FILE_EKEY_ENTRY)), CASC_EKEY_SIZE, 0); if(dwErrCode == ERROR_SUCCESS) { - dwErrCode = ProcessLocalIndexFiles(hs, InsertEncodingEKeyToMap); + dwErrCode = ProcessLocalIndexFiles(hs, InsertEncodingEKeyToMap, dwIndexCount); } } |