diff options
author | Zezula Ladislav <ladislav.zezula@avast.com> | 2017-11-08 15:31:45 +0100 |
---|---|---|
committer | Zezula Ladislav <ladislav.zezula@avast.com> | 2017-11-08 15:31:45 +0100 |
commit | dae0b690f796bd421ab69a0219cb1b46095b9f27 (patch) | |
tree | 3bb720145fdfe104b8ddecfe1e46f3419c38e8c0 /src | |
parent | 0ff84d5aed22bb5e3246cb0561592826afeb5f4a (diff) |
+ SFileAddListFile and SFileCompactArchive now take "const TCHAR *" instead of "const char *"
+ Fixed some bugs
Diffstat (limited to 'src')
-rw-r--r-- | src/FileStream.cpp | 55 | ||||
-rw-r--r-- | src/SBaseCommon.cpp | 96 | ||||
-rw-r--r-- | src/SBaseFileTable.cpp | 4 | ||||
-rw-r--r-- | src/SFileAddFile.cpp | 7 | ||||
-rw-r--r-- | src/SFileCompactArchive.cpp | 8 | ||||
-rw-r--r-- | src/SFileFindFile.cpp | 10 | ||||
-rw-r--r-- | src/SFileGetFileInfo.cpp | 2 | ||||
-rw-r--r-- | src/SFileListFile.cpp | 204 | ||||
-rw-r--r-- | src/SFileOpenFileEx.cpp | 2 | ||||
-rw-r--r-- | src/StormCommon.h | 31 | ||||
-rw-r--r-- | src/StormLib.h | 8 |
11 files changed, 234 insertions, 193 deletions
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 <typename XCHAR>
+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); |