aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'dep/CascLib/src/common')
-rw-r--r--dep/CascLib/src/common/Common.cpp105
-rw-r--r--dep/CascLib/src/common/Common.h27
-rw-r--r--dep/CascLib/src/common/ListFile.cpp28
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;
}