diff options
Diffstat (limited to 'dep/CascLib/src/common')
-rw-r--r-- | dep/CascLib/src/common/Common.cpp | 105 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.h | 27 | ||||
-rw-r--r-- | dep/CascLib/src/common/ListFile.cpp | 28 |
3 files changed, 108 insertions, 52 deletions
diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp index fafa00e7739..2860671227b 100644 --- a/dep/CascLib/src/common/Common.cpp +++ b/dep/CascLib/src/common/Common.cpp @@ -336,7 +336,7 @@ TCHAR * AppendPathFragment(TCHAR * szBuffer, TCHAR * szBufferEnd, const XCHAR * return szBuffer; } -TCHAR * GetLastPathPart(TCHAR * szWorkPath) +LPTSTR GetLastPathPart(LPTSTR szWorkPath) { size_t nLength = _tcslen(szWorkPath); @@ -375,51 +375,56 @@ bool CutLastPathPart(TCHAR * szWorkPath) return true; } -TCHAR * CombinePath(const TCHAR * szDirectory, const TCHAR * szSubDir) +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, va_list argList) { - TCHAR * szFullPathEnd; - TCHAR * szFullPath = NULL; - TCHAR * szPathPtr; - size_t nLength1 = (szDirectory != NULL) ? _tcslen(szDirectory) : 0; - size_t nLength2 = (szSubDir != NULL) ? _tcslen(szSubDir) : 0; + LPTSTR szSaveBuffer = szBuffer; + LPTSTR szBufferEnd = szBuffer + nMaxChars - 1; + LPTSTR szFragment; + bool bFirstFragment = true; - // Allocate the entire buffer - szFullPath = szPathPtr = CASC_ALLOC(TCHAR, nLength1 + nLength2 + 2); - szFullPathEnd = szFullPath + nLength1 + nLength2 + 1; - if(szFullPath != NULL) + // Combine all parts of the path here + while((szFragment = va_arg(argList, LPTSTR)) != NULL) { - szPathPtr = AppendPathFragment(szPathPtr, szFullPathEnd, szDirectory, PATH_SEP_CHAR, true); - szPathPtr = AppendPathFragment(szPathPtr, szFullPathEnd, szSubDir, PATH_SEP_CHAR); + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szFragment, chSeparator, bFirstFragment); + bFirstFragment = false; } - return szFullPath; + return (szBuffer - szSaveBuffer); } -size_t CombineFilePath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szPath, const TCHAR * szSubPath1, const TCHAR * szSubPath2) +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, ...) { - TCHAR * szSaveBuffer = szBuffer; - TCHAR * szBufferEnd = szBuffer + nMaxChars - 1; + va_list argList; + size_t nLength; - // Append all three parts and return length - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szPath, PATH_SEP_CHAR, true); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath1, PATH_SEP_CHAR); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath2, PATH_SEP_CHAR); - return (szBuffer - szSaveBuffer); + va_start(argList, chSeparator); + nLength = CombinePath(szBuffer, nMaxChars, chSeparator, argList); + va_end(argList); + + return nLength; } -size_t CombineUrlPath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szHost, const TCHAR * szSubPath1, const TCHAR * szSubPath2) +LPTSTR CombinePath(LPCTSTR szDirectory, LPCTSTR szSubDir) { - TCHAR * szSaveBuffer = szBuffer; - TCHAR * szBufferEnd = szBuffer + nMaxChars - 1; + LPTSTR szFullPath; + size_t nLength = 0; - // Append all three parts and return length - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szHost, '/', true); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath1, '/'); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath2, '/'); - return (szBuffer - szSaveBuffer); + // Calculate length + if(szDirectory != NULL) + nLength += (_tcslen(szDirectory) + 1); + if(szSubDir != NULL) + nLength += (_tcslen(szSubDir) + 1); + + // Allocate buffer + if((szFullPath = CASC_ALLOC(TCHAR, nLength)) != NULL) + { + CombinePath(szFullPath, nLength, PATH_SEP_CHAR, szDirectory, szSubDir, NULL); + } + + return szFullPath; } -size_t CreateCascSubdirectoryName(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szSubDir, const TCHAR * szExtension, LPBYTE pbEKey) +size_t CreateCascSubdirectoryName(LPTSTR szBuffer, size_t nMaxChars, LPCTSTR szSubDir, LPCTSTR szExtension, LPBYTE pbEKey) { TCHAR * szSaveBuffer = szBuffer; TCHAR * szBufferEnd = szBuffer + nMaxChars - 1; @@ -430,9 +435,10 @@ size_t CreateCascSubdirectoryName(TCHAR * szBuffer, size_t nMaxChars, const TCHA StringFromBinary(pbEKey, MD5_HASH_SIZE, szHashText); CascStrPrintf(szHashSubPath, _countof(szHashSubPath), "%02x/%02x/%s", pbEKey[0], pbEKey[1], szHashText); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubDir, '/', true); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szHashSubPath, '/'); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szExtension, '/', true); + // Combine the path together + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubDir, URL_SEP_CHAR, true); + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szHashSubPath, URL_SEP_CHAR); + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szExtension, URL_SEP_CHAR, true); return (szBuffer - szSaveBuffer); } @@ -610,16 +616,33 @@ char * StringFromMD5(LPBYTE md5, char * szBuffer) bool IsFileDataIdName(const char * szFileName, DWORD & FileDataId) { + const char * szFilePtr; BYTE BinaryValue[4]; - // File name must begin with "File", case insensitive - if(AsciiToUpperTable_BkSlash[szFileName[0]] == 'F' && - AsciiToUpperTable_BkSlash[szFileName[1]] == 'I' && - AsciiToUpperTable_BkSlash[szFileName[2]] == 'L' && - AsciiToUpperTable_BkSlash[szFileName[3]] == 'E') + // If the file name begins with "File", then a decimal file data ID must follow + if(!strncmp(szFileName, "File", 4)) + { + DWORD Accumulator = 0; + + for(szFilePtr = szFileName + 4; szFilePtr[0] != 0 && szFilePtr[0] != '.'; szFilePtr++) + { + if(!('0' <= szFilePtr[0] && szFilePtr[0] <= '9')) + return false; + Accumulator = (Accumulator * 10) + (szFilePtr[0] - '0'); + } + + if(szFilePtr[0] == '.' || szFilePtr[0] == 0) + { + FileDataId = Accumulator; + return true; + } + } + + // If the file name begins with "FILE", then a hexadecimal file data ID must follow + if(!strncmp(szFileName, "FILE", 4) && strlen(szFileName) >= 0x0C) { - // Then, 8 hexadecimal digits must follow - if(ConvertStringToBinary(szFileName + 4, 8, BinaryValue) == ERROR_SUCCESS) + // Convert the hexadecimal number to integer + if(ConvertStringToBinary(szFileName+4, 8, BinaryValue) == ERROR_SUCCESS) { // Must be followed by an extension or end-of-string if(szFileName[0x0C] == 0 || szFileName[0x0C] == '.') diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h index 705777b7b0b..45a2ec93e6b 100644 --- a/dep/CascLib/src/common/Common.h +++ b/dep/CascLib/src/common/Common.h @@ -271,10 +271,10 @@ size_t CascStrPrintf(wchar_t * buffer, size_t nCount, const wchar_t * format, .. char * CascNewStr(const char * szString, size_t nCharsToReserve = 0); wchar_t * CascNewStr(const wchar_t * szString, size_t nCharsToReserve = 0); -TCHAR * CombinePath(const TCHAR * szPath, const TCHAR * szSubDir); -size_t CombineFilePath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szPath, const TCHAR * szSubPath1, const TCHAR * szSubPath2 = NULL); -size_t CombineUrlPath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szHost, const TCHAR * szSubPath1, const TCHAR * szSubPath2 = NULL); -TCHAR * GetLastPathPart(TCHAR * szWorkPath); +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, va_list argList); +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, ...); +LPTSTR CombinePath(LPCTSTR szPath, LPCTSTR szSubDir); +LPTSTR GetLastPathPart(LPTSTR szWorkPath); bool CutLastPathPart(TCHAR * szWorkPath); size_t CreateCascSubdirectoryName(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szSubDir, const TCHAR * szExtension, LPBYTE pbEKey); @@ -383,4 +383,23 @@ int ScanIndexDirectory( void * pvContext ); +//----------------------------------------------------------------------------- +// Argument structure versioning +// Safely retrieves field value from a structure +// intended for cases where users upgrade CascLib by simply dropping in a new .dll without recompiling their app + +template <typename ARG, typename ARG_HOLDER> +bool ExtractVersionedArgument(const ARG_HOLDER * pHolder, size_t ArgOffset, ARG * pArg) +{ + if (pHolder == NULL) + return false; + + // Check input structure size + if (ArgOffset + sizeof(ARG) > pHolder->Size) + return false; + + *pArg = *((ARG *)(((char*)pHolder) + ArgOffset)); + return true; +} + #endif // __COMMON_H__ diff --git a/dep/CascLib/src/common/ListFile.cpp b/dep/CascLib/src/common/ListFile.cpp index 351ea226188..36607d39186 100644 --- a/dep/CascLib/src/common/ListFile.cpp +++ b/dep/CascLib/src/common/ListFile.cpp @@ -225,26 +225,34 @@ size_t ListFile_GetNextLine(void * pvListFile, char * szBuffer, size_t nMaxChars const char * szLineBegin = NULL; const char * szLineEnd = NULL; size_t nLength; + DWORD dwErrCode = ERROR_SUCCESS; // Retrieve the next line nLength = ListFile_GetNextLine(pvListFile, &szLineBegin, &szLineEnd); // Check the length - if(nLength > nMaxChars) + if(nLength < nMaxChars) { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return 0; + // Copy the line to the user buffer + memcpy(szBuffer, szLineBegin, nLength); + szBuffer[nLength] = 0; + } + else + { + dwErrCode = ERROR_INSUFFICIENT_BUFFER; + nLength = 0; } - // Copy the line to the user buffer - memcpy(szBuffer, szLineBegin, nLength); - szBuffer[nLength] = 0; + // If we didn't read anything, set the error code + if(nLength == 0) + SetLastError(dwErrCode); return nLength; } size_t ListFile_GetNext(void * pvListFile, char * szBuffer, size_t nMaxChars, PDWORD PtrFileDataId) { PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile; + const char * szTemp; size_t nLength = 0; int nError = ERROR_SUCCESS; @@ -257,18 +265,24 @@ size_t ListFile_GetNext(void * pvListFile, char * szBuffer, size_t nMaxChars, PD // Lines that contain bogus data, invalid numbers or too big values will be skipped if(pCache->Flags & LISTFILE_FLAG_USES_FILEDATAID) { + // Retrieve the data ID from the current position nError = ListFile_GetFileDataId(pCache, &FileDataId); if(nError == ERROR_NO_MORE_FILES) break; + + // If there was an error, skip the current line if(nError != ERROR_SUCCESS || FileDataId == CASC_INVALID_ID) + { + ListFile_GetNextLine(pvListFile, &szTemp, &szTemp); continue; + } } // Read the (next) line nLength = ListFile_GetNextLine(pvListFile, szBuffer, nMaxChars); if(nLength == 0) { - nError = ERROR_NO_MORE_FILES; + nError = GetLastError(); break; } |