diff options
Diffstat (limited to 'dep/CascLib')
-rw-r--r-- | dep/CascLib/src/CascBuildCfg.cpp | 93 | ||||
-rw-r--r-- | dep/CascLib/src/CascCommon.h | 1 | ||||
-rw-r--r-- | dep/CascLib/src/CascFindFile.cpp | 10 | ||||
-rw-r--r-- | dep/CascLib/src/CascMndxRoot.cpp | 23 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenFile.cpp | 98 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenStorage.cpp | 9 | ||||
-rw-r--r-- | dep/CascLib/src/CascReadFile.cpp | 29 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.cpp | 44 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.h | 8 | ||||
-rw-r--r-- | dep/CascLib/src/common/ListFile.cpp | 2 |
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 |