aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src
diff options
context:
space:
mode:
Diffstat (limited to 'dep/CascLib/src')
-rw-r--r--dep/CascLib/src/CascBuildCfg.cpp93
-rw-r--r--dep/CascLib/src/CascCommon.h1
-rw-r--r--dep/CascLib/src/CascFindFile.cpp10
-rw-r--r--dep/CascLib/src/CascMndxRoot.cpp23
-rw-r--r--dep/CascLib/src/CascOpenFile.cpp98
-rw-r--r--dep/CascLib/src/CascOpenStorage.cpp9
-rw-r--r--dep/CascLib/src/CascReadFile.cpp29
-rw-r--r--dep/CascLib/src/common/Common.cpp44
-rw-r--r--dep/CascLib/src/common/Common.h8
-rw-r--r--dep/CascLib/src/common/ListFile.cpp2
10 files changed, 224 insertions, 93 deletions
diff --git a/dep/CascLib/src/CascBuildCfg.cpp b/dep/CascLib/src/CascBuildCfg.cpp
index b1d6584771c..8bfc9523af7 100644
--- a/dep/CascLib/src/CascBuildCfg.cpp
+++ b/dep/CascLib/src/CascBuildCfg.cpp
@@ -37,6 +37,56 @@ static void FreeCascBlob(PQUERY_KEY pBlob)
}
}
+static DWORD GetLocaleMask(const char * szTag)
+{
+ if(!strcmp(szTag, "enUS"))
+ return CASC_LOCALE_ENUS;
+
+ if(!strcmp(szTag, "koKR"))
+ return CASC_LOCALE_KOKR;
+
+ if(!strcmp(szTag, "frFR"))
+ return CASC_LOCALE_FRFR;
+
+ if(!strcmp(szTag, "deDE"))
+ return CASC_LOCALE_DEDE;
+
+ if(!strcmp(szTag, "zhCN"))
+ return CASC_LOCALE_ZHCN;
+
+ if(!strcmp(szTag, "esES"))
+ return CASC_LOCALE_ESES;
+
+ if(!strcmp(szTag, "zhTW"))
+ return CASC_LOCALE_ZHTW;
+
+ if(!strcmp(szTag, "enGB"))
+ return CASC_LOCALE_ENGB;
+
+ if(!strcmp(szTag, "enCN"))
+ return CASC_LOCALE_ENCN;
+
+ if(!strcmp(szTag, "enTW"))
+ return CASC_LOCALE_ENTW;
+
+ if(!strcmp(szTag, "esMX"))
+ return CASC_LOCALE_ESMX;
+
+ if(!strcmp(szTag, "ruRU"))
+ return CASC_LOCALE_RURU;
+
+ if(!strcmp(szTag, "ptBR"))
+ return CASC_LOCALE_PTBR;
+
+ if(!strcmp(szTag, "itIT"))
+ return CASC_LOCALE_ITIT;
+
+ if(!strcmp(szTag, "ptPT"))
+ return CASC_LOCALE_PTPT;
+
+ return 0;
+}
+
static bool IsInfoVariable(const char * szLineBegin, const char * szLineEnd, const char * szVarName, const char * szVarType)
{
size_t nLength;
@@ -141,11 +191,11 @@ static int StringBlobToBinaryBlob(
BYTE DigitOne;
BYTE DigitTwo;
- DigitOne = (BYTE)(AsciiToUpperTable[pbBlobBegin[0]] - '0');
+ DigitOne = (BYTE)(AsciiToUpperTable_BkSlash[pbBlobBegin[0]] - '0');
if(DigitOne > 9)
DigitOne -= 'A' - '9' - 1;
- DigitTwo = (BYTE)(AsciiToUpperTable[pbBlobBegin[1]] - '0');
+ DigitTwo = (BYTE)(AsciiToUpperTable_BkSlash[pbBlobBegin[1]] - '0');
if(DigitTwo > 9)
DigitTwo -= 'A' - '9' - 1;
@@ -513,6 +563,37 @@ static int GetBuildNumber(TCascStorage * hs, LPBYTE pbVarBegin, LPBYTE pbLineEnd
return (dwBuildNumber != 0) ? ERROR_SUCCESS : ERROR_BAD_FORMAT;
}
+static int GetDefaultLocaleMask(TCascStorage * hs, PQUERY_KEY pTagsString)
+{
+ char * szTagEnd = (char *)pTagsString->pbData + pTagsString->cbData;
+ char * szTagPtr = (char *)pTagsString->pbData;
+ char * szNext;
+ DWORD dwLocaleMask = 0;
+
+ while(szTagPtr < szTagEnd)
+ {
+ // Get the next part
+ szNext = strchr(szTagPtr, ' ');
+ if(szNext != NULL)
+ *szNext++ = 0;
+
+ // Check whether the current tag is a language identifier
+ dwLocaleMask = dwLocaleMask | GetLocaleMask(szTagPtr);
+
+ // Get the next part
+ if(szNext == NULL)
+ break;
+
+ // Skip spaces
+ while(szNext < szTagEnd && szNext[0] == ' ')
+ szNext++;
+ szTagPtr = szNext;
+ }
+
+ hs->dwDefaultLocale = dwLocaleMask;
+ return ERROR_SUCCESS;
+}
+
static int FetchAndVerifyConfigFile(TCascStorage * hs, PQUERY_KEY pFileKey, PQUERY_KEY pFileBlob)
{
TCHAR * szFileName;
@@ -544,6 +625,7 @@ static int FetchAndVerifyConfigFile(TCascStorage * hs, PQUERY_KEY pFileKey, PQUE
static int ParseInfoFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
{
+ QUERY_KEY TagString = {NULL, 0};
QUERY_KEY CdnHost = {NULL, 0};
QUERY_KEY CdnPath = {NULL, 0};
const char * szLineBegin1 = NULL;
@@ -598,6 +680,8 @@ static int ParseInfoFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
LoadInfoVariable(&CdnHost, szLineBegin2, szLineEnd2, false);
if(IsInfoVariable(szLineBegin1, szLineEnd1, "CDN Path", "STRING"))
LoadInfoVariable(&CdnPath, szLineBegin2, szLineEnd2, false);
+ if(IsInfoVariable(szLineBegin1, szLineEnd1, "Tags", "STRING"))
+ LoadInfoVariable(&TagString, szLineBegin2, szLineEnd2, false);
// Move both line pointers
szLineBegin1 = SkipInfoVariable(szLineBegin1, szLineEnd1);
@@ -625,8 +709,13 @@ static int ParseInfoFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
}
}
+ // If we found tags, we can extract language build from it
+ if(TagString.pbData != NULL)
+ GetDefaultLocaleMask(hs, &TagString);
+
FreeCascBlob(&CdnHost);
FreeCascBlob(&CdnPath);
+ FreeCascBlob(&TagString);
return nError;
}
diff --git a/dep/CascLib/src/CascCommon.h b/dep/CascLib/src/CascCommon.h
index 51b6689ec16..a59cc878ec7 100644
--- a/dep/CascLib/src/CascCommon.h
+++ b/dep/CascLib/src/CascCommon.h
@@ -259,6 +259,7 @@ typedef struct _TCascStorage
DWORD dwGameInfo; // Game type
DWORD dwBuildNumber; // Game build number
DWORD dwFileBeginDelta; // This is number of bytes to shift back from archive offset (from index entry) to actual begin of file data
+ DWORD dwDefaultLocale; // Default locale, read from ".build.info"
QUERY_KEY CdnConfigKey;
QUERY_KEY CdnBuildKey;
diff --git a/dep/CascLib/src/CascFindFile.cpp b/dep/CascLib/src/CascFindFile.cpp
index 753e00a90a2..0bfe16cae1d 100644
--- a/dep/CascLib/src/CascFindFile.cpp
+++ b/dep/CascLib/src/CascFindFile.cpp
@@ -149,18 +149,22 @@ static bool DoStorageSearch_ListFile(TCascSearch * pSearch, PCASC_FIND_DATA pFin
{
PCASC_ROOT_ENTRY pRootEntry;
TCascStorage * hs = pSearch->hs;
+ char szFileName2[MAX_PATH + 1];
DWORD TableIndex = 0;
// Get next file from the listfile
while(ListFile_GetNext(pSearch->pCache, pSearch->szMask, pSearch->szFileName, MAX_PATH))
{
#ifdef _DEBUG
- //if(!_stricmp(pSearch->szFileName, "Character\\NightElf\\Female\\NightElf_FemaleFacialLowerHair01_02_HD.blp"))
- // DebugBreak();
+// if(!_stricmp(pSearch->szFileName, "Character\\BloodElf\\Female\\DeathKnightEyeGlow.blp"))
+// DebugBreak();
#endif
+ // Normalize the file name found in the list file
+ NormalizeFileName_UpperBkSlash(szFileName2, pSearch->szFileName, MAX_PATH);
+
// Find the root entry
- pRootEntry = FindRootEntry(hs, pSearch->szFileName, &TableIndex);
+ pRootEntry = FindRootEntry(hs, szFileName2, &TableIndex);
if(pRootEntry != NULL)
{
// Verify whether the file exists in the storage
diff --git a/dep/CascLib/src/CascMndxRoot.cpp b/dep/CascLib/src/CascMndxRoot.cpp
index db29fba1662..328afee8ba5 100644
--- a/dep/CascLib/src/CascMndxRoot.cpp
+++ b/dep/CascLib/src/CascMndxRoot.cpp
@@ -2872,6 +2872,14 @@ PCASC_PACKAGE FindMndxPackage(TCascStorage * hs, const char * szFileName)
assert(hs->pPackages != NULL);
pPackage = hs->pPackages->Packages;
+ //FILE * fp = fopen("E:\\packages.txt", "wt");
+ //for(size_t i = 0; i < hs->pPackages->NameEntries; i++, pPackage++)
+ //{
+ // if(pPackage->szFileName != NULL)
+ // fprintf(fp, "%s\n", pPackage->szFileName);
+ //}
+ //fclose(fp);
+
// Find the longest matching name
for(size_t i = 0; i < hs->pPackages->NameEntries; i++, pPackage++)
{
@@ -2895,7 +2903,8 @@ static bool FillFindData(TCascSearch * pSearch, PCASC_FIND_DATA pFindData, TMndx
PCASC_ROOT_ENTRY_MNDX pRootEntry = NULL;
TCascStorage * hs = pSearch->hs;
PCASC_PACKAGE pPackage;
- char * szStrippedName;
+ char * szStrippedPtr;
+ char szStrippedName[MAX_PATH+1];
int nError;
// Sanity check
@@ -2912,10 +2921,14 @@ static bool FillFindData(TCascSearch * pSearch, PCASC_FIND_DATA pFindData, TMndx
if(pPackage != NULL)
{
// Cut the package name off the full path
- szStrippedName = pFindData->szFileName + pPackage->nLength;
- while(szStrippedName[0] == '/')
- szStrippedName++;
+ szStrippedPtr = pFindData->szFileName + pPackage->nLength;
+ while(szStrippedPtr[0] == '/')
+ szStrippedPtr++;
+
+ // We need to convert the stripped name to lowercase, replacing backslashes with slashes
+ NormalizeFileName_LowerSlash(szStrippedName, szStrippedPtr, MAX_PATH);
+ // Search the package
nError = SearchMndxInfo(hs->pMndxInfo, szStrippedName, (DWORD)(pPackage - hs->pPackages->Packages), &pRootEntry);
if(nError == ERROR_SUCCESS)
{
@@ -3471,7 +3484,7 @@ void TestMndxRootFile(PCASC_MNDX_INFO pMndxInfo)
while((nLength = ListFile_GetNext(pvListFile, "*", szFileName, MAX_PATH)) != 0)
{
// Normalize the file name: ToLower + BackSlashToSlash
- NormalizeFileName_LowerSlash(szFileName);
+ NormalizeFileName_LowerSlash(szFileName, szFileName, MAX_PATH);
// Check the file with all three MAR files
TestMarFile(pMndxInfo->pMarFile1, szFileName, nLength);
diff --git a/dep/CascLib/src/CascOpenFile.cpp b/dep/CascLib/src/CascOpenFile.cpp
index e5a9855f97f..2b8c3d3c4ad 100644
--- a/dep/CascLib/src/CascOpenFile.cpp
+++ b/dep/CascLib/src/CascOpenFile.cpp
@@ -265,7 +265,7 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const char * szFileName, DWORD dwLocal
TCascStorage * hs;
QUERY_KEY EncodingKey;
char * szStrippedName;
- char * szFileName2;
+ char szFileName2[MAX_PATH+1];
int nError = ERROR_SUCCESS;
CASCLIB_UNUSED(dwLocale);
@@ -285,73 +285,63 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const char * szFileName, DWORD dwLocal
return false;
}
- // Create the copy of the file name
- szFileName2 = NewStr(szFileName, 0);
- if(szFileName2 != NULL)
+ // If the storage has a MNDX root directory, use it to search the entry
+ if(hs->pMndxInfo != NULL)
{
- // If the storage has a MNDX root directory, use it to search the entry
- if(hs->pMndxInfo != NULL)
+ // Convert the file name to lowercase + slashes
+ NormalizeFileName_LowerSlash(szFileName2, szFileName, MAX_PATH);
+
+ // Find the package number
+ pPackage = FindMndxPackage(hs, szFileName2);
+ if(pPackage != NULL)
{
- // Convert the file name to lowercase + slashes
- NormalizeFileName_LowerSlash(szFileName2);
+ // Cut the package name off the full path
+ szStrippedName = szFileName2 + pPackage->nLength;
+ while(szStrippedName[0] == '/')
+ szStrippedName++;
- // Find the package number
- pPackage = FindMndxPackage(hs, szFileName2);
- if(pPackage != NULL)
- {
- // Cut the package name off the full path
- szStrippedName = szFileName2 + pPackage->nLength;
- while(szStrippedName[0] == '/')
- szStrippedName++;
-
- nError = SearchMndxInfo(hs->pMndxInfo, szStrippedName, (DWORD)(pPackage - hs->pPackages->Packages), &pRootEntryMndx);
- if(nError == ERROR_SUCCESS)
- {
- // Prepare the encoding key
- EncodingKey.pbData = pRootEntryMndx->EncodingKey;
- EncodingKey.cbData = MD5_HASH_SIZE;
- }
- }
- else
+ nError = SearchMndxInfo(hs->pMndxInfo, szStrippedName, (DWORD)(pPackage - hs->pPackages->Packages), &pRootEntryMndx);
+ if(nError == ERROR_SUCCESS)
{
- nError = ERROR_FILE_NOT_FOUND;
+ // Prepare the encoding key
+ EncodingKey.pbData = pRootEntryMndx->EncodingKey;
+ EncodingKey.cbData = MD5_HASH_SIZE;
}
}
else
{
- // Convert the file name to lowercase + slashes
- NormalizeFileName_UpperBkSlash(szFileName2, szFileName2);
-
- // Check the root directory for that hash
- pRootEntry = FindRootEntry(hs, szFileName2, NULL);
- if(pRootEntry != NULL)
- {
- // Prepare the root key
- EncodingKey.pbData = (LPBYTE)pRootEntry->EncodingKey;
- EncodingKey.cbData = MD5_HASH_SIZE;
- nError = ERROR_SUCCESS;
- }
- else
- {
- nError = ERROR_FILE_NOT_FOUND;
- }
+ nError = ERROR_FILE_NOT_FOUND;
}
+ }
+ else
+ {
+ // Convert the file name to lowercase + slashes
+ NormalizeFileName_UpperBkSlash(szFileName2, szFileName, MAX_PATH);
- // Use the root key to find the file in the encoding table entry
- if(nError == ERROR_SUCCESS)
+ // Check the root directory for that hash
+ pRootEntry = FindRootEntry(hs, szFileName2, NULL);
+ if(pRootEntry != NULL)
{
- if(!OpenFileByEncodingKey(hs, &EncodingKey, dwFlags, (TCascFile **)phFile))
- {
- assert(GetLastError() != ERROR_SUCCESS);
- nError = GetLastError();
- }
+ // Prepare the root key
+ EncodingKey.pbData = (LPBYTE)pRootEntry->EncodingKey;
+ EncodingKey.cbData = MD5_HASH_SIZE;
+ nError = ERROR_SUCCESS;
+ }
+ else
+ {
+ nError = ERROR_FILE_NOT_FOUND;
}
+ }
- // Delete the file name copy
- CASC_FREE(szFileName2);
+ // Use the root key to find the file in the encoding table entry
+ if(nError == ERROR_SUCCESS)
+ {
+ if(!OpenFileByEncodingKey(hs, &EncodingKey, dwFlags, (TCascFile **)phFile))
+ {
+ assert(GetLastError() != ERROR_SUCCESS);
+ nError = GetLastError();
+ }
}
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
#ifdef CASCLIB_TEST
if(phFile[0] != NULL && pRootEntryMndx != NULL)
diff --git a/dep/CascLib/src/CascOpenStorage.cpp b/dep/CascLib/src/CascOpenStorage.cpp
index 490d889742f..6a8d83ee903 100644
--- a/dep/CascLib/src/CascOpenStorage.cpp
+++ b/dep/CascLib/src/CascOpenStorage.cpp
@@ -677,7 +677,7 @@ static LPBYTE LoadEncodingFileToMemory(HANDLE hFile, DWORD * pcbEncodingFile)
DWORD cbEncodingFile = 0;
DWORD dwSegmentPos = 0;
DWORD dwNumSegments = 0;
- DWORD dwBytesRead;
+ DWORD dwBytesRead = 0;
int nError = ERROR_BAD_FORMAT;
// Read the encoding header
@@ -724,7 +724,7 @@ static LPBYTE LoadRootFileToMemory(HANDLE hFile, DWORD * pcbRootFile)
TCascFile * hf;
LPBYTE pbRootFile = NULL;
DWORD cbRootFile = 0;
- DWORD dwBytesRead;
+ DWORD dwBytesRead = 0;
BYTE StartOfFile[0x10];
int nError = ERROR_SUCCESS;
@@ -1105,9 +1105,9 @@ static int LoadRootFile(TCascStorage * hs, DWORD dwLocaleMask)
assert(hs->ppEncodingEntries != NULL);
// Locale: The default parameter is 0 - in that case,
- // we load enUS+enGB
+ // we assign the default locale, loaded from the .build.info file
if(dwLocaleMask == 0)
- dwLocaleMask = CASC_LOCALE_ENUS | CASC_LOCALE_ENGB;
+ dwLocaleMask = hs->dwDefaultLocale;
// The root file is either MNDX file (Heroes of the Storm)
// or a file containing an array of root entries (World of Warcraft 6.0+)
@@ -1243,6 +1243,7 @@ bool WINAPI CascOpenStorage(const TCHAR * szDataPath, DWORD dwLocaleMask, HANDLE
memset(hs, 0, sizeof(TCascStorage));
hs->szClassName = "TCascStorage";
hs->dwFileBeginDelta = 0xFFFFFFFF;
+ hs->dwDefaultLocale = CASC_LOCALE_ENUS | CASC_LOCALE_ENGB;
hs->dwRefCount = 1;
nError = InitializeCascDirectories(hs, szDataPath);
}
diff --git a/dep/CascLib/src/CascReadFile.cpp b/dep/CascLib/src/CascReadFile.cpp
index d35da531ec4..83fdd0d2096 100644
--- a/dep/CascLib/src/CascReadFile.cpp
+++ b/dep/CascLib/src/CascReadFile.cpp
@@ -379,13 +379,16 @@ DWORD WINAPI CascSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHig
bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDWORD pdwBytesRead)
{
PCASC_FILE_FRAME pFrame = NULL;
+ ULONGLONG StreamSize;
ULONGLONG FileOffset;
TCascFile * hf;
LPBYTE pbBuffer = (LPBYTE)pvBuffer;
DWORD dwStartPointer = 0;
DWORD dwFilePointer = 0;
DWORD dwEndPointer = 0;
+ DWORD dwFrameSize;
DWORD cbOutBuffer;
+ bool bReadResult;
int nError = ERROR_SUCCESS;
// The buffer must be valid
@@ -463,7 +466,31 @@ bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDW
// Load the raw file data to memory
FileOffset = pFrame->FrameArchiveOffset;
- if(!FileStream_Read(hf->pStream, &FileOffset, pbRawData, pFrame->CompressedSize))
+ bReadResult = FileStream_Read(hf->pStream, &FileOffset, pbRawData, pFrame->CompressedSize);
+
+ // Note: The raw file data size could be less than expected
+ // Happened in WoW build 19342 with the ROOT file. MD5 in the frame header
+ // is zeroed, which means it should not be checked
+ // Frame File: data.029
+ // Frame Offs: 0x013ED9F0 size 0x01325B32
+ // Frame End: 0x02713522
+ // File Size: 0x027134FC
+ if(bReadResult == false && GetLastError() == ERROR_HANDLE_EOF && !IsValidMD5(pFrame->md5))
+ {
+ // Get the size of the remaining file
+ FileStream_GetSize(hf->pStream, &StreamSize);
+ dwFrameSize = (DWORD)(StreamSize - FileOffset);
+
+ // If the frame offset is before EOF and frame end is beyond EOF, correct it
+ if(FileOffset < StreamSize && dwFrameSize < pFrame->CompressedSize)
+ {
+ memset(pbRawData + dwFrameSize, 0, (pFrame->CompressedSize - dwFrameSize));
+ bReadResult = true;
+ }
+ }
+
+ // If the read result failed, we cannot finish reading it
+ if(bReadResult == false)
{
CASC_FREE(pbRawData);
nError = GetLastError();
diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp
index 74f86d44853..2dbdd470478 100644
--- a/dep/CascLib/src/common/Common.cpp
+++ b/dep/CascLib/src/common/Common.cpp
@@ -16,15 +16,15 @@
// Conversion to uppercase/lowercase
// Converts ASCII characters to lowercase
-// Converts slash (0x2F) to backslash (0x5C)
-unsigned char AsciiToLowerTable[256] =
+// Converts backslash (0x5C) to normal slash (0x2F)
+unsigned char AsciiToLowerTable_Slash[256] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x5C,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x2F, 0x5D, 0x5E, 0x5F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
@@ -39,7 +39,7 @@ unsigned char AsciiToLowerTable[256] =
// Converts ASCII characters to uppercase
// Converts slash (0x2F) to backslash (0x5C)
-unsigned char AsciiToUpperTable[256] =
+unsigned char AsciiToUpperTable_BkSlash[256] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
@@ -218,31 +218,37 @@ TCHAR * CombinePath(const TCHAR * szDirectory, const TCHAR * szSubDir)
return szFullPath;
}
-void NormalizeFileName_UpperBkSlash(const char * szSrcFileName, char * szTrgFileName)
+void NormalizeFileName_UpperBkSlash(char * szTrgFileName, const char * szSrcFileName, size_t cchMaxChars)
{
+ char * szTrgFileEnd = szTrgFileName + cchMaxChars;
size_t i;
// Normalize the file name: ToLower + BackSlashToSlash
- for(i = 0; szSrcFileName[i] != 0; i++)
- szTrgFileName[i] = AsciiToUpperTable[szSrcFileName[i]];
+ for(i = 0; szSrcFileName[i] != 0 && szTrgFileName < szTrgFileEnd; i++)
+ szTrgFileName[i] = AsciiToUpperTable_BkSlash[szSrcFileName[i]];
+
+ assert(szSrcFileName[i] == 0);
szTrgFileName[i] = 0;
}
-void NormalizeFileName_LowerSlash(char * szFileName)
+void NormalizeFileName_LowerSlash(char * szTrgFileName, const char * szSrcFileName, size_t cchMaxChars)
{
+ char * szTrgFileEnd = szTrgFileName + cchMaxChars;
+ size_t i;
+
// Normalize the file name: ToLower + BackSlashToSlash
- for(size_t i = 0; szFileName[i] != 0; i++)
- {
- szFileName[i] = AsciiToLowerTable[szFileName[i]];
- szFileName[i] = (szFileName[i] != '\\') ? szFileName[i] : '/';
- }
+ for(i = 0; szSrcFileName[i] != 0 && szTrgFileName < szTrgFileEnd; i++)
+ szTrgFileName[i] = AsciiToLowerTable_Slash[szSrcFileName[i]];
+
+ assert(szSrcFileName[i] == 0);
+ szTrgFileName[i] = 0;
}
int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue)
{
BYTE Digit;
- Digit = (BYTE)(AsciiToUpperTable[szString[0]] - _T('0'));
+ Digit = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - _T('0'));
if(Digit > 9)
Digit -= 'A' - '9' - 1;
@@ -266,11 +272,11 @@ int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrVa
BYTE DigitOne;
BYTE DigitTwo;
- DigitOne = (BYTE)(AsciiToUpperTable[szString[0]] - _T('0'));
+ DigitOne = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - _T('0'));
if(DigitOne > 9)
DigitOne -= 'A' - '9' - 1;
- DigitTwo = (BYTE)(AsciiToUpperTable[szString[1]] - _T('0'));
+ DigitTwo = (BYTE)(AsciiToUpperTable_BkSlash[szString[1]] - _T('0'));
if(DigitTwo > 9)
DigitTwo -= 'A' - '9' - 1;
@@ -383,7 +389,7 @@ bool CheckWildCard(const char * szString, const char * szWildCard)
// Calculate match count
while(nMatchCount < nSubStringLength)
{
- if(AsciiToUpperTable[(BYTE)szString[nMatchCount]] != AsciiToUpperTable[(BYTE)szWildCard[nMatchCount]])
+ if(AsciiToUpperTable_BkSlash[(BYTE)szString[nMatchCount]] != AsciiToUpperTable_BkSlash[(BYTE)szWildCard[nMatchCount]])
break;
if(szString[nMatchCount] == 0)
break;
@@ -406,7 +412,7 @@ bool CheckWildCard(const char * szString, const char * szWildCard)
else
{
// If we came to the end of the string, compare it to the wildcard
- if(AsciiToUpperTable[(BYTE)*szString] != AsciiToUpperTable[(BYTE)*szWildCard])
+ if(AsciiToUpperTable_BkSlash[(BYTE)*szString] != AsciiToUpperTable_BkSlash[(BYTE)*szWildCard])
return false;
// If we arrived to the end of the string, it's a match
diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h
index 40712b99eed..ae098adb084 100644
--- a/dep/CascLib/src/common/Common.h
+++ b/dep/CascLib/src/common/Common.h
@@ -24,8 +24,8 @@
//-----------------------------------------------------------------------------
// Conversion tables
-extern unsigned char AsciiToLowerTable[256];
-extern unsigned char AsciiToUpperTable[256];
+extern unsigned char AsciiToLowerTable_Slash[256];
+extern unsigned char AsciiToUpperTable_BkSlash[256];
extern unsigned char IntToHexChar[];
//-----------------------------------------------------------------------------
@@ -50,8 +50,8 @@ TCHAR * NewStrFromAnsi(LPBYTE pbStringBegin, LPBYTE pbStringEnd);
TCHAR * CombinePath(const TCHAR * szPath, const TCHAR * szSubDir);
-void NormalizeFileName_UpperBkSlash(const char * szSrcFileName, char * szTrgFileName);
-void NormalizeFileName_LowerSlash(char * szFileName);
+void NormalizeFileName_UpperBkSlash(char * szTrgFileName, const char * szSrcFileName, size_t cchMaxChars);
+void NormalizeFileName_LowerSlash(char * szTrgFileName, const char * szSrcFileName, size_t cchMaxChars);
int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue);
int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue);
diff --git a/dep/CascLib/src/common/ListFile.cpp b/dep/CascLib/src/common/ListFile.cpp
index 8e0b1374241..42131a2bc2c 100644
--- a/dep/CascLib/src/common/ListFile.cpp
+++ b/dep/CascLib/src/common/ListFile.cpp
@@ -316,7 +316,7 @@ static PLISTFILE_MAP ListMap_InsertName(PLISTFILE_MAP pListMap, const char * szF
pListEntry = (PLISTFILE_ENTRY)((LPBYTE)(pListMap + 1) + pListMap->cbBuffer);
// Get the name hash
- NormalizeFileName_UpperBkSlash(szFileName, szFileName2);
+ NormalizeFileName_UpperBkSlash(szFileName2, szFileName, MAX_PATH);
hashlittle2(szFileName2, nLength, &dwHashHigh, &dwHashLow);
// Calculate the HASH value of the normalized file name