From dae0b690f796bd421ab69a0219cb1b46095b9f27 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Wed, 8 Nov 2017 15:31:45 +0100 Subject: + SFileAddListFile and SFileCompactArchive now take "const TCHAR *" instead of "const char *" + Fixed some bugs --- src/FileStream.cpp | 55 ------------ src/SBaseCommon.cpp | 96 ++++++++++++++------- src/SBaseFileTable.cpp | 4 +- src/SFileAddFile.cpp | 7 +- src/SFileCompactArchive.cpp | 8 +- src/SFileFindFile.cpp | 10 +-- src/SFileGetFileInfo.cpp | 2 +- src/SFileListFile.cpp | 204 +++++++++++++++++++++++++++----------------- src/SFileOpenFileEx.cpp | 2 +- src/StormCommon.h | 31 +++++-- src/StormLib.h | 8 +- 11 files changed, 234 insertions(+), 193 deletions(-) (limited to 'src') diff --git a/src/FileStream.cpp b/src/FileStream.cpp index b2370ff..c73223c 100644 --- a/src/FileStream.cpp +++ b/src/FileStream.cpp @@ -2826,58 +2826,3 @@ void FileStream_Close(TFileStream * pStream) STORM_FREE(pStream); } } - -//----------------------------------------------------------------------------- -// Utility functions (ANSI) - -const char * GetPlainFileName(const char * szFileName) -{ - const char * szPlainName = szFileName; - - while(*szFileName != 0) - { - if(*szFileName == '\\' || *szFileName == '/') - szPlainName = szFileName + 1; - szFileName++; - } - - return szPlainName; -} - -void CopyFileName(char * szTarget, const char * szSource, size_t cchLength) -{ - memcpy(szTarget, szSource, cchLength); - szTarget[cchLength] = 0; -} - -//----------------------------------------------------------------------------- -// Utility functions (UNICODE) only exist in the ANSI version of the library -// In ANSI builds, TCHAR = char, so we don't need these functions implemented - -#ifdef _UNICODE -const TCHAR * GetPlainFileName(const TCHAR * szFileName) -{ - const TCHAR * szPlainName = szFileName; - - while(*szFileName != 0) - { - if(*szFileName == '\\' || *szFileName == '/') - szPlainName = szFileName + 1; - szFileName++; - } - - return szPlainName; -} - -void CopyFileName(TCHAR * szTarget, const char * szSource, size_t cchLength) -{ - mbstowcs(szTarget, szSource, cchLength); - szTarget[cchLength] = 0; -} - -void CopyFileName(char * szTarget, const TCHAR * szSource, size_t cchLength) -{ - wcstombs(szTarget, szSource, cchLength); - szTarget[cchLength] = 0; -} -#endif diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index aa891df..a131380 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -93,55 +93,93 @@ unsigned char AsciiToUpperTable_Slash[256] = }; //----------------------------------------------------------------------------- -// Safe string functions +// Safe string functions (for ANSI builds) -void StringCopyA(char * dest, const char * src, size_t nMaxChars) +void StringCopy(char * szTarget, size_t cchTarget, const char * szSource) { - size_t nLength = strlen(src); + if(cchTarget > 0) + { + size_t cchSource = strlen(szSource); - // Don't copy more than nMaxChars - nLength = STORMLIB_MIN(nLength, nMaxChars); - memcpy(dest, src, nLength); - dest[nLength] = 0; + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + memcpy(szTarget, szSource, cchSource); + szTarget[cchSource] = 0; + } } -void StringCatA(char * dest, const char * src, size_t nMaxChars) +void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource) +{ + // Get the current length of the target + size_t cchTarget = strlen(szTarget); + + // Copy the string to the target + if(cchTarget < cchTargetMax) + { + StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource); + } +} + +//----------------------------------------------------------------------------- +// Utility functions (UNICODE) only exist in the ANSI version of the library +// In ANSI builds, TCHAR = char, so we don't need these functions implemented + +#ifdef _UNICODE +void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource) { - size_t nLength1 = strlen(dest); - size_t nLength2 = strlen(src); + if(cchTarget > 0) + { + size_t cchSource = strlen(szSource); + + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + mbstowcs(szTarget, szSource, cchSource); + szTarget[cchSource] = 0; + } +} - // Don't copy more than nMaxChars - if(nLength1 < nMaxChars) +void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource) +{ + if(cchTarget > 0) { - nLength2 = STORMLIB_MIN(nLength2, (nMaxChars - nLength1)); - memcpy(dest + nLength1, src, nLength2); - dest[nLength1 + nLength2] = 0; + size_t cchSource = _tcslen(szSource); + + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + wcstombs(szTarget, szSource, cchSource); + szTarget[cchSource] = 0; } } -void StringCopyT(TCHAR * dest, const TCHAR * src, size_t nMaxChars) +void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource) { - size_t nLength = _tcslen(src); + if(cchTarget > 0) + { + size_t cchSource = _tcslen(szSource); - // Don't copy more than nMaxChars - nLength = STORMLIB_MIN(nLength, nMaxChars); - memcpy(dest, src, (nLength * sizeof(TCHAR))); - dest[nLength] = 0; + if(cchSource >= cchTarget) + cchSource = cchTarget - 1; + + memcpy(szTarget, szSource, cchSource * sizeof(TCHAR)); + szTarget[cchSource] = 0; + } } -void StringCatT(TCHAR * dest, const TCHAR * src, size_t nMaxChars) +void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource) { - size_t nLength1 = _tcslen(dest); - size_t nLength2 = _tcslen(src); + // Get the current length of the target + size_t cchTarget = _tcslen(szTarget); - // Don't copy more than nMaxChars - if(nLength1 < nMaxChars) + // Copy the string to the target + if(cchTarget < cchTargetMax) { - nLength2 = STORMLIB_MIN(nLength2, (nMaxChars - nLength1)); - memcpy(dest + nLength1, src, (nLength2 * sizeof(TCHAR))); - dest[nLength1 + nLength2] = 0; + StringCopy(szTarget + cchTarget, (cchTargetMax - cchTarget), szSource); } } +#endif //----------------------------------------------------------------------------- // Storm hashing functions diff --git a/src/SBaseFileTable.cpp b/src/SBaseFileTable.cpp index 39ba125..1cb469e 100644 --- a/src/SBaseFileTable.cpp +++ b/src/SBaseFileTable.cpp @@ -891,8 +891,8 @@ TMPQBlock * TranslateBlockTable( TFileEntry * pFileEntry = ha->pFileTable; TMPQBlock * pBlockTable; TMPQBlock * pBlock; - DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize; DWORD NeedHiBlockTable = 0; + DWORD dwBlockTableSize = ha->pHeader->dwBlockTableSize; // Allocate copy of the hash table pBlockTable = pBlock = STORM_ALLOC(TMPQBlock, dwBlockTableSize); @@ -2617,7 +2617,7 @@ int DefragmentFileTable(TMPQArchive * ha) pTarget++; // Update the block table size - dwBlockTableSize = (DWORD)(pSource - ha->pFileTable) + 1; + dwBlockTableSize = (DWORD)(pTarget - ha->pFileTable); } else { diff --git a/src/SFileAddFile.cpp b/src/SFileAddFile.cpp index 376813b..7dd583f 100644 --- a/src/SFileAddFile.cpp +++ b/src/SFileAddFile.cpp @@ -451,12 +451,11 @@ int SFileAddFile_Init( } else { - // Free all internal files - (listfile), (attributes), (signature) - InvalidateInternalFiles(ha); - // Attempt to allocate new file entry pFileEntry = AllocateFileEntry(ha, szFileName, lcLocale, &dwHashIndex); - if(pFileEntry == NULL) + if(pFileEntry != NULL) + InvalidateInternalFiles(ha); + else nError = ERROR_DISK_FULL; } diff --git a/src/SFileCompactArchive.cpp b/src/SFileCompactArchive.cpp index 2895baa..ff7b25b 100644 --- a/src/SFileCompactArchive.cpp +++ b/src/SFileCompactArchive.cpp @@ -46,7 +46,7 @@ static int CheckIfAllFilesKnown(TMPQArchive * ha) return nError; } -static int CheckIfAllKeysKnown(TMPQArchive * ha, const char * szListFile, LPDWORD pFileKeys) +static int CheckIfAllKeysKnown(TMPQArchive * ha, const TCHAR * szListFile, LPDWORD pFileKeys) { TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; TFileEntry * pFileEntry; @@ -523,7 +523,7 @@ bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK pfnCompa return true; } -bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bReserved */) +bool WINAPI SFileCompactArchive(HANDLE hMpq, const TCHAR * szListFile, bool /* bReserved */) { TFileStream * pTempStream = NULL; TMPQArchive * ha = (TMPQArchive *)hMpq; @@ -568,8 +568,8 @@ bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bR if(nError == ERROR_SUCCESS) { // Create temporary file name. Prevent buffer overflow - StringCopyT(szTempFile, FileStream_GetFileName(ha->pStream), MAX_PATH); - StringCatT(szTempFile, _T(".tmp"), MAX_PATH); + StringCopy(szTempFile, _countof(szTempFile), FileStream_GetFileName(ha->pStream)); + StringCat(szTempFile, _countof(szTempFile), _T(".tmp")); // Create temporary file pTempStream = FileStream_CreateFile(szTempFile, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp index 3533549..68e769d 100644 --- a/src/SFileFindFile.cpp +++ b/src/SFileFindFile.cpp @@ -190,9 +190,9 @@ static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry) szFileName[0] = 0; // Prepare the prefix for the file name - if(ha->pPatchPrefix != NULL) - StringCopyA(szFileName, ha->pPatchPrefix->szPatchPrefix, MAX_PATH); - StringCatA(szFileName, pFileEntry->szFileName, MAX_PATH); + if(ha->pPatchPrefix && ha->pPatchPrefix->nLength) + StringCopy(szFileName, _countof(szFileName), ha->pPatchPrefix->szPatchPrefix); + StringCat(szFileName, _countof(szFileName), pFileEntry->szFileName); // Try to find the file there pTempEntry = GetFileEntryExact(ha, szFileName, 0, NULL); @@ -275,7 +275,7 @@ static bool DoMPQSearch_FileEntry( } // Fill the file name and plain file name - StringCopyA(lpFindFileData->cFileName, szFileName + nPrefixLength, MAX_PATH-1); + StringCopy(lpFindFileData->cFileName, _countof(lpFindFileData->cFileName), szFileName + nPrefixLength); lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName); return true; } @@ -378,7 +378,7 @@ static void FreeMPQSearch(TMPQSearch *& hs) //----------------------------------------------------------------------------- // Public functions -HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile) +HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const TCHAR * szListFile) { TMPQArchive * ha = (TMPQArchive *)hMpq; TMPQSearch * hs = NULL; diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp index 4f15501..00b76ca 100644 --- a/src/SFileGetFileInfo.cpp +++ b/src/SFileGetFileInfo.cpp @@ -990,7 +990,7 @@ bool WINAPI SFileGetFileName(HANDLE hFile, char * szFileName) if(szFileName != NULL) { const TCHAR * szStreamName = FileStream_GetFileName(hf->pStream); - CopyFileName(szFileName, szStreamName, _tcslen(szStreamName)); + StringCopy(szFileName, MAX_PATH, szStreamName); } nError = ERROR_SUCCESS; } diff --git a/src/SFileListFile.cpp b/src/SFileListFile.cpp index 588eca4..3fa695f 100644 --- a/src/SFileListFile.cpp +++ b/src/SFileListFile.cpp @@ -19,17 +19,26 @@ #define CACHE_BUFFER_SIZE 0x1000 // Size of the cache buffer #define MAX_LISTFILE_SIZE 0x04000000 // Maximum accepted listfile size is about 68 MB +union TListFileHandle +{ + TFileStream * pStream; // Opened local file + HANDLE hFile; // Opened MPQ file +}; + struct TListFileCache { char * szWildCard; // Self-relative pointer to file mask LPBYTE pBegin; // The begin of the listfile cache LPBYTE pPos; // Current position in the cache LPBYTE pEnd; // The last character in the file cache + DWORD dwFlags; // Flags from TMPQArchive // char szWildCard[wildcard_length]; // Followed by the name mask (if any) // char szListFile[listfile_length]; // Followed by the listfile (if any) }; +typedef bool (*LOAD_LISTFILE)(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead); + //----------------------------------------------------------------------------- // Local functions (cache) @@ -45,6 +54,22 @@ static char * CopyListLine(char * szListLine, const char * szFileName) return szListLine; } +static bool LoadListFile_Stream(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead) +{ + ULONGLONG ByteOffset = 0; + bool bResult; + + bResult = FileStream_Read(pHandle->pStream, &ByteOffset, pvBuffer, cbBuffer); + if(bResult) + *pdwBytesRead = cbBuffer; + return bResult; +} + +static bool LoadListFile_MPQ(TListFileHandle * pHandle, void * pvBuffer, DWORD cbBuffer, LPDWORD pdwBytesRead) +{ + return SFileReadFile(pHandle->hFile, pvBuffer, cbBuffer, pdwBytesRead, NULL); +} + static bool FreeListFileCache(TListFileCache * pCache) { // Valid parameter check @@ -53,16 +78,20 @@ static bool FreeListFileCache(TListFileCache * pCache) return true; } -static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szWildCard) +static TListFileCache * CreateListFileCache( + LOAD_LISTFILE PfnLoadFile, + TListFileHandle * pHandle, + const char * szWildCard, + DWORD dwFileSize, + DWORD dwMaxSize, + DWORD dwFlags) { TListFileCache * pCache = NULL; size_t cchWildCard = 0; DWORD dwBytesRead = 0; - DWORD dwFileSize; // Get the amount of bytes that need to be allocated - dwFileSize = SFileGetFileSize(hListFile, NULL); - if(dwFileSize == 0 || dwFileSize > MAX_LISTFILE_SIZE) + if(dwFileSize == 0 || dwFileSize > dwMaxSize) return NULL; // Append buffer for name mask, if any @@ -75,6 +104,7 @@ static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szWil { // Clear the entire structure memset(pCache, 0, sizeof(TListFileCache) + cchWildCard); + pCache->dwFlags = dwFlags; // Shall we copy the mask? if(cchWildCard != 0) @@ -87,7 +117,7 @@ static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szWil pCache->pBegin = (LPBYTE)(pCache + 1) + cchWildCard; // Load the entire listfile to the cache - SFileReadFile(hListFile, pCache->pBegin, dwFileSize, &dwBytesRead, NULL); + PfnLoadFile(pHandle, pCache->pBegin, dwFileSize, &dwBytesRead); if(dwBytesRead != 0) { // Allocate pointers @@ -105,6 +135,68 @@ static TListFileCache * CreateListFileCache(HANDLE hListFile, const char * szWil return pCache; } +static TListFileCache * CreateListFileCache( + HANDLE hMpq, + const TCHAR * szListFile, + const char * szWildCard, + DWORD dwMaxSize, + DWORD dwFlags) +{ + TListFileCache * pCache = NULL; + TListFileHandle ListHandle = {NULL}; + + // Internal listfile: hMPQ must be non NULL and szListFile must be NULL. + // We load the MPQ::(listfile) file + if(hMpq != NULL && szListFile == NULL) + { + DWORD dwFileSize = 0; + + // Open the file from the MPQ + if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &ListHandle.hFile)) + { + // Get the file size and create the listfile cache + dwFileSize = SFileGetFileSize(ListHandle.hFile, NULL); + pCache = CreateListFileCache(LoadListFile_MPQ, &ListHandle, szWildCard, dwFileSize, dwMaxSize, dwFlags); + + // Close the MPQ file + SFileCloseFile(ListHandle.hFile); + } + + // Return the loaded cache + return pCache; + } + + // External listfile: hMpq must be NULL and szListFile must be non-NULL. + // We load the file using TFileStream + if(hMpq == NULL && szListFile != NULL) + { + ULONGLONG FileSize = 0; + + // Open the local file + ListHandle.pStream = FileStream_OpenFile(szListFile, STREAM_FLAG_READ_ONLY); + if(ListHandle.pStream != NULL) + { + // Verify the file size + FileStream_GetSize(ListHandle.pStream, &FileSize); + if(0 < FileSize && FileSize < MAX_LISTFILE_SIZE) + { + pCache = CreateListFileCache(LoadListFile_Stream, &ListHandle, szWildCard, (DWORD)FileSize, dwMaxSize, dwFlags); + } + + // Close the stream + FileStream_Close(ListHandle.pStream); + } + + // Return the loaded cache + return pCache; + } + + // This combination should never happen + SetLastError(ERROR_INVALID_PARAMETER); + assert(false); + return NULL; +} + #ifdef _DEBUG /* TMPQNameCache * CreateNameCache(HANDLE hListFile, const char * szSearchMask) @@ -423,12 +515,14 @@ int SListFileSaveToMpq(TMPQArchive * ha) static int SFileAddArbitraryListFile( TMPQArchive * ha, - HANDLE hListFile) + HANDLE hMpq, + const TCHAR * szListFile, + DWORD dwMaxSize) { TListFileCache * pCache = NULL; // Create the listfile cache for that file - pCache = CreateListFileCache(hListFile, NULL); + pCache = CreateListFileCache(hMpq, szListFile, NULL, dwMaxSize, ha->dwFlags); if(pCache != NULL) { char * szFileName; @@ -449,79 +543,44 @@ static int SFileAddArbitraryListFile( return (pCache != NULL) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; } -static int SFileAddExternalListFile( - TMPQArchive * ha, - HANDLE hMpq, - const char * szListFile) -{ - HANDLE hListFile; - int nError = ERROR_SUCCESS; - - // Open the external list file - if(!SFileOpenFileEx(hMpq, szListFile, SFILE_OPEN_LOCAL_FILE, &hListFile)) - return GetLastError(); - - // Add the data from the listfile to MPQ - nError = SFileAddArbitraryListFile(ha, hListFile); - SFileCloseFile(hListFile); - return nError; -} - static int SFileAddInternalListFile( TMPQArchive * ha, HANDLE hMpq) { TMPQHash * pFirstHash; TMPQHash * pHash; - HANDLE hListFile; - DWORD dwFileSize; LCID lcSaveLocale = lcFileLocale; - bool bIgnoreListFile = false; + DWORD dwMaxSize = MAX_LISTFILE_SIZE; int nError = ERROR_SUCCESS; // If there is hash table, we need to support multiple listfiles // with different locales (BrooDat.mpq) if(ha->pHashTable != NULL) { + // If the archive is a malformed map, ignore too large listfiles + if(ha->dwFlags & MPQ_FLAG_MALFORMED) + dwMaxSize = 0x40000; + pFirstHash = pHash = GetFirstHashEntry(ha, LISTFILE_NAME); while(nError == ERROR_SUCCESS && pHash != NULL) { // Set the prefered locale to that from list file SFileSetLocale(pHash->lcLocale); - - // Attempt to open the file with that locale - if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile)) - { - // If the archive is a malformed map, ignore too large listfiles - if(ha->dwFlags & MPQ_FLAG_MALFORMED) - { - dwFileSize = SFileGetFileSize(hListFile, NULL); - bIgnoreListFile = (dwFileSize > 0x40000); - } - // Add the data from the listfile to MPQ - if(bIgnoreListFile == false) - nError = SFileAddArbitraryListFile(ha, hListFile); - SFileCloseFile(hListFile); - } - - // Restore the original locale - SFileSetLocale(lcSaveLocale); + // Add that listfile + nError = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize); // Move to the next hash pHash = GetNextHashEntry(ha, pFirstHash, pHash); } + + // Restore the original locale + SFileSetLocale(lcSaveLocale); } else { - // Open the external list file - if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile)) - { - // Add the data from the listfile to MPQ - // The function also closes the listfile handle - nError = SFileAddArbitraryListFile(ha, hListFile); - SFileCloseFile(hListFile); - } + // Add the single listfile + nError = SFileAddArbitraryListFile(ha, hMpq, NULL, dwMaxSize); } // Return the result of the operation @@ -562,7 +621,7 @@ static bool DoListFileSearch(TListFileCache * pCache, SFILE_FIND_DATA * lpFindFi // File functions // Adds a listfile into the MPQ archive. -int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile) +int WINAPI SFileAddListFile(HANDLE hMpq, const TCHAR * szListFile) { TMPQArchive * ha = (TMPQArchive *)hMpq; int nError = ERROR_SUCCESS; @@ -571,7 +630,7 @@ int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile) while(ha != NULL) { if(szListFile != NULL) - nError = SFileAddExternalListFile(ha, hMpq, szListFile); + nError = SFileAddArbitraryListFile(ha, NULL, szListFile, MAX_LISTFILE_SIZE); else nError = SFileAddInternalListFile(ha, hMpq); @@ -591,37 +650,24 @@ int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile) //----------------------------------------------------------------------------- // Enumerating files in listfile -HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData) +HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const TCHAR * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData) { TListFileCache * pCache = NULL; - HANDLE hListFile = NULL; - DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE; // Initialize the structure with zeros memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); - // If the szListFile is NULL, it means we have to open internal listfile - if(szListFile == NULL) - { - // Use SFILE_OPEN_ANY_LOCALE for listfile. This will allow us to load - // the listfile even if there is only non-neutral version of the listfile in the MPQ - dwSearchScope = SFILE_OPEN_ANY_LOCALE; - szListFile = LISTFILE_NAME; - } - // Open the local/internal listfile - if(SFileOpenFileEx(hMpq, szListFile, dwSearchScope, &hListFile)) - { - pCache = CreateListFileCache(hListFile, szMask); - SFileCloseFile(hListFile); - } - - if(!DoListFileSearch(pCache, lpFindFileData)) + pCache = CreateListFileCache(hMpq, szListFile, szMask, 0, 0); + if(pCache != NULL) { - memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); - SetLastError(ERROR_NO_MORE_FILES); - FreeListFileCache(pCache); - pCache = NULL; + if(!DoListFileSearch(pCache, lpFindFileData)) + { + memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA)); + SetLastError(ERROR_NO_MORE_FILES); + FreeListFileCache(pCache); + pCache = NULL; + } } // Return the listfile cache as handle diff --git a/src/SFileOpenFileEx.cpp b/src/SFileOpenFileEx.cpp index 9ce0ae2..6e4af14 100644 --- a/src/SFileOpenFileEx.cpp +++ b/src/SFileOpenFileEx.cpp @@ -75,7 +75,7 @@ static bool OpenLocalFile(const char * szFileName, HANDLE * PtrFile) TCHAR szFileNameT[MAX_PATH]; // Convert the file name to UNICODE (if needed) - CopyFileName(szFileNameT, szFileName, strlen(szFileName)); + StringCopy(szFileNameT, _countof(szFileNameT), szFileName); // Open the file and create the TMPQFile structure pStream = FileStream_OpenFile(szFileNameT, STREAM_FLAG_READ_ONLY); diff --git a/src/StormCommon.h b/src/StormCommon.h index 868f1c1..95b72a3 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -133,11 +133,15 @@ extern unsigned char AsciiToUpperTable[256]; //----------------------------------------------------------------------------- // Safe string functions -void StringCopyA(char * dest, const char * src, size_t nMaxChars); -void StringCatA(char * dest, const char * src, size_t nMaxChars); - -void StringCopyT(TCHAR * dest, const TCHAR * src, size_t nMaxChars); -void StringCatT(TCHAR * dest, const TCHAR * src, size_t nMaxChars); +void StringCopy(char * szTarget, size_t cchTarget, const char * szSource); +void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource); + +#ifdef _UNICODE +void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource); +void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource); +void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource); +void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource); +#endif //----------------------------------------------------------------------------- // Encryption and decryption functions @@ -296,11 +300,20 @@ void Patch_Finalize(TMPQPatcher * pPatcher); bool CheckWildCard(const char * szString, const char * szWildCard); bool IsInternalMpqFileName(const char * szFileName); -const TCHAR * GetPlainFileName(const TCHAR * szFileName); -const char * GetPlainFileName(const char * szFileName); +template +const XCHAR * GetPlainFileName(const XCHAR * szFileName) +{ + const XCHAR * szPlainName = szFileName; + + while(*szFileName != 0) + { + if(*szFileName == '\\' || *szFileName == '/') + szPlainName = szFileName + 1; + szFileName++; + } -void CopyFileName(TCHAR * szTarget, const char * szSource, size_t cchLength); -void CopyFileName(char * szTarget, const TCHAR * szSource, size_t cchLength); + return szPlainName; +} //----------------------------------------------------------------------------- // Internal support for MPQ modifications diff --git a/src/StormLib.h b/src/StormLib.h index 45dda2e..07defcc 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -998,11 +998,11 @@ bool WINAPI SFileCloseArchive(HANDLE hMpq); // Adds another listfile into MPQ. The currently added listfile(s) remain, // so you can use this API to combining more listfiles. // Note that this function is internally called by SFileFindFirstFile -int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile); +int WINAPI SFileAddListFile(HANDLE hMpq, const TCHAR * szListFile); // Archive compacting bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK CompactCB, void * pvUserData); -bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool bReserved); +bool WINAPI SFileCompactArchive(HANDLE hMpq, const TCHAR * szListFile, bool bReserved); // Changing the maximum file count DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq); @@ -1058,11 +1058,11 @@ DWORD WINAPI SFileVerifyArchive(HANDLE hMpq); //----------------------------------------------------------------------------- // Functions for file searching -HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const char * szListFile); +HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const TCHAR * szListFile); bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); bool WINAPI SFileFindClose(HANDLE hFind); -HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData); +HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const TCHAR * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData); bool WINAPI SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData); bool WINAPI SListFileFindClose(HANDLE hFind); -- cgit v1.2.3