From 999ee276cfd7420abaf7566932b591677aff184f Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Thu, 2 Feb 2023 00:22:24 +0100 Subject: Fixed bugs --- src/SBaseFileTable.cpp | 2 +- src/SFileFindFile.cpp | 7 +++++-- src/SFileGetFileInfo.cpp | 42 +++++++++++++++++++++--------------------- src/SFileListFile.cpp | 2 +- src/SFileVerify.cpp | 17 ++++++++++++----- src/StormCommon.h | 3 +++ 6 files changed, 43 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index 2fd717b..43202d0 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -683,7 +683,7 @@ DWORD ConvertMpqHeaderToFormat4( return ERROR_FAKE_MPQ_HEADER; // Check for malformed MPQs - if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ByteOffset + pHeader->ArchiveSize64) != FileSize || (ByteOffset + pHeader->HiBlockTablePos64) >= FileSize) + if(pHeader->wFormatVersion != MPQ_FORMAT_VERSION_4 || (ByteOffset + pHeader->ArchiveSize64) > FileSize || (ByteOffset + pHeader->HiBlockTablePos64) >= FileSize) { pHeader->wFormatVersion = MPQ_FORMAT_VERSION_4; pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V4; diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp index 4de1022..b741e5f 100644 --- a/src/SFileFindFile.cpp +++ b/src/SFileFindFile.cpp @@ -213,7 +213,7 @@ static bool DoMPQSearch_FileEntry( TFileEntry * pPatchEntry; HANDLE hFile = NULL; const char * szFileName; - size_t nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0; + size_t nGlobalPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0; DWORD dwBlockIndex; char szNameBuff[MAX_PATH]; @@ -227,6 +227,8 @@ static bool DoMPQSearch_FileEntry( // Now we have to check if this file was not enumerated before if(!FileWasFoundBefore(ha, hs, pFileEntry)) { + size_t nPrefixLength = nGlobalPrefixLength; + // if(pFileEntry != NULL && !_stricmp(pFileEntry->szFileName, "TriggerLibs\\NativeLib.galaxy")) // DebugBreak(); @@ -246,8 +248,9 @@ static bool DoMPQSearch_FileEntry( if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile)) { SFileGetFileName(hFile, szNameBuff); - szFileName = szNameBuff; SFileCloseFile(hFile); + szFileName = szNameBuff; + nPrefixLength = 0; } } diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp index 77c86fd..f9b9a76 100644 --- a/src/SFileGetFileInfo.cpp +++ b/src/SFileGetFileInfo.cpp @@ -42,7 +42,7 @@ static DWORD GetMpqFileCount(TMPQArchive * ha) return dwFileCount; } -static bool GetInfo_ReturdwErrCode(DWORD dwErrCode) +static bool GetInfo_ReturnError(DWORD dwErrCode) { SetLastError(dwErrCode); return false; @@ -56,11 +56,11 @@ static bool GetInfo_BufferCheck(void * pvFileInfo, DWORD cbFileInfo, DWORD cbDat // Check for sufficient buffer if(cbData > cbFileInfo) - return GetInfo_ReturdwErrCode(ERROR_INSUFFICIENT_BUFFER); + return GetInfo_ReturnError(ERROR_INSUFFICIENT_BUFFER); // If the buffer size is sufficient, check for valid user buffer if(pvFileInfo == NULL) - return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReturnError(ERROR_INVALID_PARAMETER); // Buffers and sizes are OK, we are ready to proceed file copying return true; @@ -150,7 +150,7 @@ static bool GetInfo_PatchChain(TMPQFile * hf, void * pvFileInfo, DWORD cbFileInf // Patch chain is only supported on MPQ files. Local files are not supported. if(hf->pStream != NULL) - return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReturnError(ERROR_INVALID_PARAMETER); // Calculate the necessary length of the multi-string for(hfTemp = hf; hfTemp != NULL; hfTemp = hfTemp->hfPatch) @@ -209,13 +209,13 @@ bool WINAPI SFileGetFileInfo( if((int)InfoClass <= (int)SFileMpqFlags) { if((ha = IsValidMpqHandle(hMpqOrFile)) == NULL) - return GetInfo_ReturdwErrCode(ERROR_INVALID_HANDLE); + return GetInfo_ReturnError(ERROR_INVALID_HANDLE); pHeader = ha->pHeader; } else { if((hf = IsValidFileHandle(hMpqOrFile)) == NULL) - return GetInfo_ReturdwErrCode(ERROR_INVALID_HANDLE); + return GetInfo_ReturnError(ERROR_INVALID_HANDLE); pFileEntry = hf->pFileEntry; } @@ -235,12 +235,12 @@ bool WINAPI SFileGetFileInfo( case SFileMpqUserDataHeader: if(ha->pUserData == NULL) - return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReturnError(ERROR_INVALID_PARAMETER); return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos, sizeof(TMPQUserData), pcbLengthNeeded); case SFileMpqUserData: if(ha->pUserData == NULL) - return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReturnError(ERROR_INVALID_PARAMETER); return GetInfo_ReadFromFile(pvFileInfo, cbFileInfo, ha->pStream, ha->UserDataPos + sizeof(TMPQUserData), ha->pUserData->dwHeaderOffs - sizeof(TMPQUserData), pcbLengthNeeded); case SFileMpqHeaderOffset: @@ -261,12 +261,12 @@ bool WINAPI SFileGetFileInfo( case SFileMpqHetHeader: pvSrcFileInfo = LoadExtTable(ha, pHeader->HetTablePos64, (size_t)pHeader->HetTableSize64, HET_TABLE_SIGNATURE, MPQ_KEY_HASH_TABLE); if(pvSrcFileInfo == NULL) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, sizeof(TMPQHetHeader), pcbLengthNeeded); case SFileMpqHetTable: if((pvSrcFileInfo = LoadHetTable(ha)) == NULL) - return GetInfo_ReturdwErrCode(ERROR_NOT_ENOUGH_MEMORY); + return GetInfo_ReturnError(ERROR_NOT_ENOUGH_MEMORY); return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded); case SFileMpqBetTableOffset: @@ -280,7 +280,7 @@ bool WINAPI SFileGetFileInfo( // Retrieve the table and its size pvSrcFileInfo = LoadExtTable(ha, pHeader->BetTablePos64, (size_t)pHeader->BetTableSize64, BET_TABLE_SIGNATURE, MPQ_KEY_BLOCK_TABLE); if(pvSrcFileInfo == NULL) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); cbSrcFileInfo = sizeof(TMPQBetHeader) + ((TMPQBetHeader *)pvSrcFileInfo)->dwFlagCount * sizeof(DWORD); // It is allowed for the caller to only require BET header @@ -290,7 +290,7 @@ bool WINAPI SFileGetFileInfo( case SFileMpqBetTable: if((pvSrcFileInfo = LoadBetTable(ha)) == NULL) - return GetInfo_ReturdwErrCode(ERROR_NOT_ENOUGH_MEMORY); + return GetInfo_ReturnError(ERROR_NOT_ENOUGH_MEMORY); return GetInfo_TablePointer(pvFileInfo, cbFileInfo, pvSrcFileInfo, InfoClass, pcbLengthNeeded); case SFileMpqHashTableOffset: @@ -320,7 +320,7 @@ bool WINAPI SFileGetFileInfo( case SFileMpqBlockTable: ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos)); if(ByteOffset >= ha->FileSize) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); cbSrcFileInfo = pHeader->dwBlockTableSize * sizeof(TMPQBlock); pvSrcFileInfo = LoadBlockTable(ha, true); return GetInfo_Allocated(pvFileInfo, cbFileInfo, pvSrcFileInfo, cbSrcFileInfo, pcbLengthNeeded); @@ -332,27 +332,27 @@ bool WINAPI SFileGetFileInfo( return GetInfo(pvFileInfo, cbFileInfo, &pHeader->HiBlockTableSize64, sizeof(ULONGLONG), pcbLengthNeeded); case SFileMpqHiBlockTable: - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); case SFileMpqSignatures: if(!QueryMpqSignatureInfo(ha, &SignatureInfo)) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.SignatureTypes, sizeof(DWORD), pcbLengthNeeded); case SFileMpqStrongSignatureOffset: if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); return GetInfo(pvFileInfo, cbFileInfo, &SignatureInfo.EndMpqData, sizeof(ULONGLONG), pcbLengthNeeded); case SFileMpqStrongSignatureSize: if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); dwInt32Value = MPQ_STRONG_SIGNATURE_SIZE + 4; return GetInfo(pvFileInfo, cbFileInfo, &dwInt32Value, sizeof(DWORD), pcbLengthNeeded); case SFileMpqStrongSignature: if(QueryMpqSignatureInfo(ha, &SignatureInfo) == false || (SignatureInfo.SignatureTypes & SIGNATURE_TYPE_STRONG) == 0) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); return GetInfo(pvFileInfo, cbFileInfo, SignatureInfo.Signature, MPQ_STRONG_SIGNATURE_SIZE + 4, pcbLengthNeeded); case SFileMpqArchiveSize64: @@ -376,7 +376,7 @@ bool WINAPI SFileGetFileInfo( case SFileMpqRawChunkSize: if(pHeader->dwRawChunkSize == 0) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); return GetInfo(pvFileInfo, cbFileInfo, &pHeader->dwRawChunkSize, sizeof(DWORD), pcbLengthNeeded); case SFileMpqStreamFlags: @@ -391,7 +391,7 @@ bool WINAPI SFileGetFileInfo( case SFileInfoFileEntry: if(pFileEntry == NULL) - return GetInfo_ReturdwErrCode(ERROR_FILE_NOT_FOUND); + return GetInfo_ReturnError(ERROR_FILE_NOT_FOUND); return GetInfo_FileEntry(pvFileInfo, cbFileInfo, pFileEntry, pcbLengthNeeded); case SFileInfoHashEntry: @@ -445,7 +445,7 @@ bool WINAPI SFileGetFileInfo( return GetInfo(pvFileInfo, cbFileInfo, &hf->pFileEntry->dwCrc32, sizeof(DWORD), pcbLengthNeeded); default: // Invalid info class - return GetInfo_ReturdwErrCode(ERROR_INVALID_PARAMETER); + return GetInfo_ReturnError(ERROR_INVALID_PARAMETER); } } diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp index 6adf1ab..2a3f02a 100644 --- a/src/SFileListFile.cpp +++ b/src/SFileListFile.cpp @@ -573,7 +573,7 @@ static DWORD SFileAddInternalListFile( if(ha->pHashTable != NULL) { // If the archive is a malformed map, ignore too large listfiles - if(ha->dwFlags & MPQ_FLAG_MALFORMED) + if(STORMLIB_TEST_FLAGS(ha->dwFlags, MPQ_FLAG_MALFORMED | MPQ_FLAG_PATCH, MPQ_FLAG_MALFORMED)) dwMaxSize = 0x40000; pFirstHash = pHash = GetFirstHashEntry(ha, LISTFILE_NAME); diff --git a/src/SFileVerify.cpp b/src/SFileVerify.cpp index 4c8c181..3748918 100644 --- a/src/SFileVerify.cpp +++ b/src/SFileVerify.cpp @@ -801,11 +801,11 @@ DWORD SSignFileCreate(TMPQArchive * ha) // Create the (signature) file file in the MPQ // Note that the file must not be compressed or encrypted dwErrCode = SFileAddFile_Init(ha, SIGNATURE_NAME, - 0, - sizeof(EmptySignature), - LANG_NEUTRAL, - ha->dwFileFlags3 | MPQ_FILE_REPLACEEXISTING, - &hf); + 0, + sizeof(EmptySignature), + LANG_NEUTRAL, + ha->dwFileFlags3 | MPQ_FILE_REPLACEEXISTING, + &hf); // Write the empty signature file to the archive if(dwErrCode == ERROR_SUCCESS) @@ -813,6 +813,13 @@ DWORD SSignFileCreate(TMPQArchive * ha) // Write the empty zeroed file to the MPQ memset(EmptySignature, 0, sizeof(EmptySignature)); dwErrCode = SFileAddFile_Write(hf, EmptySignature, (DWORD)sizeof(EmptySignature), 0); + } + + // Finalize the signature + if(dwErrCode == ERROR_SUCCESS) + { + // Clear the CRC as it will not be valid + hf->pFileEntry->dwCrc32 = hf->dwCrc32 = 0; SFileAddFile_Finish(hf); // Clear the invalid mark diff --git a/src/StormCommon.h b/src/StormCommon.h index 39f7524..74b687e 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -70,6 +70,9 @@ // Checks for data pointers aligned to 4-byte boundary #define STORMLIB_DWORD_ALIGNED(ptr) (((size_t)(ptr) & 0x03) == 0) +// Check for masked flags +#define STORMLIB_TEST_FLAGS(dwFlags, dwMask, dwValue) ((dwFlags & (dwMask)) == (dwValue)) + // Macro for building 64-bit file offset from two 32-bit #define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo) -- cgit v1.2.3