diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-11-05 20:52:53 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-12-08 18:16:46 +0100 |
commit | 6b6d5aff0530d43875572edc9616bc788ed8a26c (patch) | |
tree | 8d0ad02913e4b625b2b2c26d3daff9b8a354360c /dep/CascLib/src | |
parent | 5095bcbf1cf57dae0e58e1d1251b566952352047 (diff) |
Dep/CascLib: Update to ladislav-zezula/CascLib@737a8705b5b8f7ce3917f5d5ff9767b18de1285e
Diffstat (limited to 'dep/CascLib/src')
-rw-r--r-- | dep/CascLib/src/CascCommon.h | 3 | ||||
-rw-r--r-- | dep/CascLib/src/CascDecrypt.cpp | 450 | ||||
-rw-r--r-- | dep/CascLib/src/CascFiles.cpp | 14 | ||||
-rw-r--r-- | dep/CascLib/src/CascFindFile.cpp | 10 | ||||
-rw-r--r-- | dep/CascLib/src/CascIndexFiles.cpp | 18 | ||||
-rw-r--r-- | dep/CascLib/src/CascLib.h | 12 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenFile.cpp | 22 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenStorage.cpp | 26 | ||||
-rw-r--r-- | dep/CascLib/src/CascPort.h | 33 | ||||
-rw-r--r-- | dep/CascLib/src/CascReadFile.cpp | 44 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_OW.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_Text.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_WoW.cpp | 4 | ||||
-rw-r--r-- | dep/CascLib/src/DllMain.def (renamed from dep/CascLib/src/CascLib.def) | 0 | ||||
-rw-r--r-- | dep/CascLib/src/DllMain.rc | 20 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.cpp | 129 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.h | 82 | ||||
-rw-r--r-- | dep/CascLib/src/common/Csv.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/FileStream.cpp | 94 | ||||
-rw-r--r-- | dep/CascLib/src/common/ListFile.cpp | 6 | ||||
-rw-r--r-- | dep/CascLib/src/common/Map.h | 23 |
21 files changed, 579 insertions, 417 deletions
diff --git a/dep/CascLib/src/CascCommon.h b/dep/CascLib/src/CascCommon.h index 8ef9d557a51..aa0aff876ce 100644 --- a/dep/CascLib/src/CascCommon.h +++ b/dep/CascLib/src/CascCommon.h @@ -329,8 +329,7 @@ struct TCascStorage size_t EKeyLength; // EKey length from the index files DWORD FileOffsetBits; // Number of bits in the storage offset which mean data segent offset - CASC_ARRAY ExtraKeysList; // List additional encryption keys - CASC_MAP EncryptionKeys; // Map of encryption keys + CASC_KEY_MAP KeyMap; // Growable map of encryption keys ULONGLONG LastFailKeyName; // The value of the encryption key that recently was NOT found. }; diff --git a/dep/CascLib/src/CascDecrypt.cpp b/dep/CascLib/src/CascDecrypt.cpp index ccce1fc0a5b..3dbb5ce31a6 100644 --- a/dep/CascLib/src/CascDecrypt.cpp +++ b/dep/CascLib/src/CascDecrypt.cpp @@ -15,14 +15,7 @@ //----------------------------------------------------------------------------- // Local structures -#define CASC_EXTRA_KEYS 0x80 - -typedef struct _CASC_ENCRYPTION_KEY -{ - ULONGLONG KeyName; // "Name" of the key - BYTE Key[CASC_KEY_LENGTH]; // The key itself -} CASC_ENCRYPTION_KEY, *PCASC_ENCRYPTION_KEY; - +// For Salsa20 decryption process typedef struct _CASC_SALSA20 { DWORD Key[CASC_KEY_LENGTH]; @@ -30,26 +23,40 @@ typedef struct _CASC_SALSA20 } CASC_SALSA20, *PCASC_SALSA20; +// For static-stored keys +struct CASC_ENCRYPTION_KEY +{ + ULONGLONG KeyName; // "Name" of the key + BYTE Key[CASC_KEY_LENGTH]; // The key itself +}; + +// For keys inside the key map +struct CASC_ENCRYPTION_KEY2 : public CASC_ENCRYPTION_KEY +{ + CASC_ENCRYPTION_KEY2 * pNext; // Pointer to the next key wihh the same hash +}; +typedef CASC_ENCRYPTION_KEY2 * PCASC_ENCRYPTION_KEY2; + //----------------------------------------------------------------------------- // Known encryption keys. See https://wowdev.wiki/CASC for updates static const char * szKeyConstant16 = "expand 16-byte k"; static const char * szKeyConstant32 = "expand 32-byte k"; -static CASC_ENCRYPTION_KEY CascKeys[] = +static CASC_ENCRYPTION_KEY StaticCascKeys[] = { // Key Name Encryption key Seen in - // ---------------------- ------------------------------------------------------------------------------------------------ ----------- + // ---------------------- --------------------------------------------------------------------------------------------------- ----------- // Battle.net app { 0x2C547F26A2613E01ULL, { 0x37, 0xC5, 0x0C, 0x10, 0x2D, 0x4C, 0x9E, 0x3A, 0x5A, 0xC0, 0x69, 0xF0, 0x72, 0xB1, 0x41, 0x7D } }, // Battle.net App Alpha 1.5.0 // Starcraft -// { 0xD0CAE11366CEEA83ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? }}, // 1.12.3.2609 (build 45364) +// { 0xD0CAE11366CEEA83ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 1.12.3.2609 (build 45364) // Warcraft III Reforged beta (build) - { 0x6E4296823E7D561EULL, { 0xC0, 0xBF, 0xA2, 0x94, 0x3A, 0xC3, 0xE9, 0x22, 0x86, 0xE4, 0x44, 0x3E, 0xE3, 0x56, 0x0D, 0x65 }}, // 1.32.0.13369 Base content (Beta Week 0) - { 0xE04D60E31DDEBF63ULL, { 0x26, 0x3D, 0xB5, 0xC4, 0x02, 0xDA, 0x8D, 0x4D, 0x68, 0x63, 0x09, 0xCB, 0x2E, 0x32, 0x54, 0xD0 }}, // 1.32.0.13445 Base content (Beta Week 1) + { 0x6E4296823E7D561EULL, { 0xC0, 0xBF, 0xA2, 0x94, 0x3A, 0xC3, 0xE9, 0x22, 0x86, 0xE4, 0x44, 0x3E, 0xE3, 0x56, 0x0D, 0x65 } }, // 1.32.0.13369 Base content (Beta Week 0) + { 0xE04D60E31DDEBF63ULL, { 0x26, 0x3D, 0xB5, 0xC4, 0x02, 0xDA, 0x8D, 0x4D, 0x68, 0x63, 0x09, 0xCB, 0x2E, 0x32, 0x54, 0xD0 } }, // 1.32.0.13445 Base content (Beta Week 1) // Overwatch { 0xFB680CB6A8BF81F3ULL, { 0x62, 0xD9, 0x0E, 0xFA, 0x7F, 0x36, 0xD7, 0x1C, 0x39, 0x8A, 0xE2, 0xF1, 0xFE, 0x37, 0xBD, 0xB9 } }, // 0.8.0.24919_retailx64 (hardcoded) @@ -644,12 +651,98 @@ static int Decrypt_Salsa20(LPBYTE pbOutBuffer, LPBYTE pbInBuffer, size_t cbInBuf return Decrypt(&SalsaState, pbOutBuffer, pbInBuffer, cbInBuffer); } -static LPBYTE CascFindKey(TCascStorage * hs, ULONGLONG KeyName) +//----------------------------------------------------------------------------- +// Key map implementation + +static PCASC_ENCRYPTION_KEY2 CreateKeyItem(ULONGLONG KeyName, LPBYTE Key) +{ + PCASC_ENCRYPTION_KEY2 pNewItem; + + if((pNewItem = new CASC_ENCRYPTION_KEY2) != NULL) + { + memset(pNewItem, 0, sizeof(CASC_ENCRYPTION_KEY2)); + pNewItem->KeyName = KeyName; + memcpy(pNewItem->Key, Key, CASC_KEY_LENGTH); + } + + return pNewItem; +} + +CASC_KEY_MAP::CASC_KEY_MAP() +{ + memset(HashTable, 0, sizeof(HashTable)); +} + +CASC_KEY_MAP::~CASC_KEY_MAP() +{ + PCASC_ENCRYPTION_KEY2 pNextItem; + PCASC_ENCRYPTION_KEY2 pKeyItem; + + for(size_t i = 0; i < CASC_KEY_TABLE_SIZE; i++) + { + if((pKeyItem = (PCASC_ENCRYPTION_KEY2)HashTable[i]) != NULL) + { + while(pKeyItem != NULL) + { + pNextItem = pKeyItem->pNext; + delete pKeyItem; + pKeyItem = pNextItem; + } + } + } +} + +LPBYTE CASC_KEY_MAP::FindKey(ULONGLONG KeyName) { - PCASC_ENCRYPTION_KEY pKey; + PCASC_ENCRYPTION_KEY2 pKeyItem = NULL; + size_t HashIndex = (size_t)(KeyName & CASC_KEY_TABLE_MASK); + + // Check the key chain beginning at the hash table + pKeyItem = (PCASC_ENCRYPTION_KEY2)HashTable[HashIndex]; + while(pKeyItem != NULL) + { + if(pKeyItem->KeyName == KeyName) + return pKeyItem->Key; + pKeyItem = pKeyItem->pNext; + } - pKey = (PCASC_ENCRYPTION_KEY)hs->EncryptionKeys.FindObject(&KeyName); - return (pKey != NULL) ? pKey->Key : NULL; + // Not found + return NULL; +} + +bool CASC_KEY_MAP::AddKey(ULONGLONG KeyName, LPBYTE Key) +{ + PCASC_ENCRYPTION_KEY2 pKeyItem; + PCASC_ENCRYPTION_KEY2 pNewItem; + size_t HashIndex = (size_t)(KeyName & CASC_KEY_TABLE_MASK); + + // Is the key already there? + if(FindKey(KeyName) == NULL) + { + // Create new key item + if((pNewItem = CreateKeyItem(KeyName, Key)) == NULL) + return false; + + if(HashTable[HashIndex] != NULL) + { + // Get the last-in-chain key item + pKeyItem = (PCASC_ENCRYPTION_KEY2)(HashTable[HashIndex]); + while(pKeyItem->pNext != NULL) + pKeyItem = pKeyItem->pNext; + + // Insert the key to the chain + pKeyItem->pNext = pNewItem; + return true; + } + else + { + HashTable[HashIndex] = pNewItem; + return true; + } + } + + // Already exists, it's OK + return true; } //----------------------------------------------------------------------------- @@ -657,22 +750,197 @@ static LPBYTE CascFindKey(TCascStorage * hs, ULONGLONG KeyName) DWORD CascLoadEncryptionKeys(TCascStorage * hs) { - size_t nKeyCount = (sizeof(CascKeys) / sizeof(CASC_ENCRYPTION_KEY)); - size_t nMaxItems = nKeyCount + CASC_EXTRA_KEYS; - DWORD dwErrCode; + for(size_t i = 0; i < _countof(StaticCascKeys); i++) + { + if(!hs->KeyMap.AddKey(StaticCascKeys[i].KeyName, StaticCascKeys[i].Key)) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + } + + return ERROR_SUCCESS; +} + +bool WINAPI CascAddEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPBYTE Key) +{ + TCascStorage * hs; + + // Validate the storage handle + hs = TCascStorage::IsValid(hStorage); + if (hs == NULL) + { + SetCascError(ERROR_INVALID_HANDLE); + return false; + } + + // Add the key to the map and return result + return hs->KeyMap.AddKey(KeyName, Key); +} + +bool WINAPI CascAddStringEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPCSTR szKey) +{ + BYTE Key[CASC_KEY_LENGTH]; + + // Check the length of the string key + if(strlen(szKey) != CASC_KEY_LENGTH * 2) + { + SetCascError(ERROR_INVALID_PARAMETER); + return false; + } + + // Convert the string key to the binary array + if(BinaryFromString(szKey, CASC_KEY_LENGTH * 2, Key) != ERROR_SUCCESS) + { + SetCascError(ERROR_INVALID_PARAMETER); + return false; + } + + return CascAddEncryptionKey(hStorage, KeyName, Key); +} - // Create fast map of KeyName -> Key - dwErrCode = hs->EncryptionKeys.Create(nMaxItems, sizeof(ULONGLONG), FIELD_OFFSET(CASC_ENCRYPTION_KEY, KeyName)); - if(dwErrCode != ERROR_SUCCESS) - return dwErrCode; +LPBYTE WINAPI CascFindEncryptionKey(HANDLE hStorage, ULONGLONG KeyName) +{ + TCascStorage * hs; - // Insert all static keys - for (size_t i = 0; i < nKeyCount; i++) - hs->EncryptionKeys.InsertObject(&CascKeys[i], &CascKeys[i].KeyName); + // Validate the storage handle + hs = TCascStorage::IsValid(hStorage); + if (hs == NULL) + { + SetCascError(ERROR_INVALID_HANDLE); + return NULL; + } - // Create array for extra keys - dwErrCode = hs->ExtraKeysList.Create<CASC_ENCRYPTION_KEY>(CASC_EXTRA_KEYS); - return dwErrCode; + // Return the result from the map's search function + return hs->KeyMap.FindKey(KeyName); +} + +bool WINAPI CascGetNotFoundEncryptionKey(HANDLE hStorage, ULONGLONG * KeyName) +{ + TCascStorage * hs; + + // Validate the storage handle + if ((hs = TCascStorage::IsValid(hStorage)) == NULL) + { + SetCascError(ERROR_INVALID_HANDLE); + return false; + } + + // If there was no decryption key error, just return false with ERROR_SUCCESS + if(hs->LastFailKeyName == 0) + { + SetCascError(ERROR_SUCCESS); + return false; + } + + // Give the name of the key that failed most recently + KeyName[0] = hs->LastFailKeyName; + return true; +} + +bool WINAPI CascImportKeysFromString(HANDLE hStorage, LPCSTR szKeyList) +{ + // Verify parameters + if(TCascStorage::IsValid(hStorage) == NULL || szKeyList == NULL || szKeyList[0] == 0) + { + SetCascError(ERROR_INVALID_PARAMETER); + return false; + } + + // Parse text file + while(szKeyList[0]) + { + ULONGLONG KeyName = 0; + DWORD dwErrCode; + BYTE KeyValue[CASC_KEY_LENGTH]; + + // Capture key name + dwErrCode = ConvertStringToInt(szKeyList, 0, KeyName, &szKeyList); + if(dwErrCode != ERROR_SUCCESS) + { + SetCascError(dwErrCode); + return false; + } + + // TACT key list downloaded from https://wow.tools/api.php?type=tactkeys ends with a single zero + if(KeyName == 0) + break; + + // We only expect spaces and tabs at this point. Anything else will lead + // to end of the loop. + while(szKeyList[0] == 0x09 || szKeyList[0] == 0x20) + szKeyList++; + if(szKeyList[0] == 0x0A || szKeyList[0] == 0x0D) + break; + + // Convert the string to binary + dwErrCode = BinaryFromString(szKeyList, CASC_KEY_LENGTH * 2, KeyValue); + if(dwErrCode != ERROR_SUCCESS) + { + SetCascError(dwErrCode); + return false; + } + + // Add the encryption key. Note that if the key already exists with the same value, + // CascAddEncryptionKey will consider it success. + if(!CascAddEncryptionKey(hStorage, KeyName, KeyValue)) + return false; + + // Move to the next key + while(szKeyList[0] != 0 && szKeyList[0] != 0x0A && szKeyList[0] != 0x0D) + szKeyList++; + while(szKeyList[0] == 0x0A || szKeyList[0] == 0x0D) + szKeyList++; + } + + return true; +} + +bool WINAPI CascImportKeysFromFile(HANDLE hStorage, LPCTSTR szFileName) +{ + TFileStream * pFileStream; + ULONGLONG FileSize = 0; + LPSTR szKeyList; + bool bResult = false; + + // Open the file + if((pFileStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY)) != NULL) + { + // Load the entire file to memory, up to 10 MB + if(FileStream_GetSize(pFileStream, &FileSize) && FileSize < 0xA00000) + { + DWORD FileSize32 = (DWORD)FileSize; + + // Allocate buffer for the key stream + if((szKeyList = CASC_ALLOC<char>(FileSize32 + 1)) != NULL) + { + // Read the entire file and terminate it with zero + FileStream_Read(pFileStream, NULL, szKeyList, FileSize32); + szKeyList[FileSize] = 0; + + // Import the buffer + bResult = CascImportKeysFromString(hStorage, szKeyList); + CASC_FREE(szKeyList); + } + } + else + SetCascError(ERROR_FILE_TOO_LARGE); + + FileStream_Close(pFileStream); + } + + return bResult; +} + +DWORD CascDirectCopy(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer) +{ + // Check the buffer size + if((cbInBuffer - 1) > pcbOutBuffer[0]) + return ERROR_INSUFFICIENT_BUFFER; + + // Copy the data + memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); + pcbOutBuffer[0] = cbInBuffer; + return ERROR_SUCCESS; } DWORD CascDecrypt(TCascStorage * hs, LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer, DWORD dwFrameIndex) @@ -726,7 +994,7 @@ DWORD CascDecrypt(TCascStorage * hs, LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LP return ERROR_INSUFFICIENT_BUFFER; // Check if we know the key - pbKey = CascFindKey(hs, KeyName); + pbKey = hs->KeyMap.FindKey(KeyName); if(pbKey == NULL) { hs->LastFailKeyName = KeyName; @@ -754,126 +1022,10 @@ DWORD CascDecrypt(TCascStorage * hs, LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LP pcbOutBuffer[0] = (DWORD)(pbBufferEnd - pbInBuffer); return ERROR_SUCCESS; -// case 'A': -// return ERROR_NOT_SUPPORTED; + // case 'A': + // return ERROR_NOT_SUPPORTED; } assert(false); return ERROR_NOT_SUPPORTED; } - -DWORD CascDirectCopy(LPBYTE pbOutBuffer, PDWORD pcbOutBuffer, LPBYTE pbInBuffer, DWORD cbInBuffer) -{ - // Check the buffer size - if((cbInBuffer - 1) > pcbOutBuffer[0]) - return ERROR_INSUFFICIENT_BUFFER; - - // Copy the data - memcpy(pbOutBuffer, pbInBuffer, cbInBuffer); - pcbOutBuffer[0] = cbInBuffer; - return ERROR_SUCCESS; -} - -//----------------------------------------------------------------------------- -// Public functions - -bool WINAPI CascAddEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPBYTE Key) -{ - PCASC_ENCRYPTION_KEY pEncKey; - TCascStorage * hs; - - // Validate the storage handle - hs = TCascStorage::IsValid(hStorage); - if (hs == NULL) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // Don't allow more than CASC_EXTRA_KEYS keys - if (hs->ExtraKeysList.ItemCount() >= CASC_EXTRA_KEYS) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return false; - } - - // Insert the key to the array - pEncKey = (PCASC_ENCRYPTION_KEY)hs->ExtraKeysList.Insert(1); - if (pEncKey == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return false; - } - - // Fill the key - memcpy(pEncKey->Key, Key, sizeof(pEncKey->Key)); - pEncKey->KeyName = KeyName; - - // Also insert the key to the map - if (!hs->EncryptionKeys.InsertObject(pEncKey, &pEncKey->KeyName)) - { - SetLastError(ERROR_ALREADY_EXISTS); - return false; - } - - return true; -} - -bool WINAPI CascAddStringEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPCSTR szKey) -{ - BYTE Key[CASC_KEY_LENGTH]; - - // Check the length of the string key - if(strlen(szKey) != CASC_KEY_LENGTH * 2) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - // Convert the string key to the binary array - if(ConvertStringToBinary(szKey, CASC_KEY_LENGTH * 2, Key) != ERROR_SUCCESS) - { - SetLastError(ERROR_INVALID_PARAMETER); - return false; - } - - return CascAddEncryptionKey(hStorage, KeyName, Key); -} - -LPBYTE WINAPI CascFindEncryptionKey(HANDLE hStorage, ULONGLONG KeyName) -{ - TCascStorage * hs; - - // Validate the storage handle - hs = TCascStorage::IsValid(hStorage); - if (hs == NULL) - { - SetLastError(ERROR_INVALID_HANDLE); - return NULL; - } - - return CascFindKey(hs, KeyName); -} - -bool WINAPI CascGetNotFoundEncryptionKey(HANDLE hStorage, ULONGLONG * KeyName) -{ - TCascStorage * hs; - - // Validate the storage handle - if ((hs = TCascStorage::IsValid(hStorage)) == NULL) - { - SetLastError(ERROR_INVALID_HANDLE); - return false; - } - - // If there was no decryption key error, just return false with ERROR_SUCCESS - if(hs->LastFailKeyName == 0) - { - SetLastError(ERROR_SUCCESS); - return false; - } - - // Give the name of the key that failed most recently - KeyName[0] = hs->LastFailKeyName; - return true; -} diff --git a/dep/CascLib/src/CascFiles.cpp b/dep/CascLib/src/CascFiles.cpp index c1a9e648c72..596a07d3362 100644 --- a/dep/CascLib/src/CascFiles.cpp +++ b/dep/CascLib/src/CascFiles.cpp @@ -153,7 +153,7 @@ static const char * CaptureSingleHash(const char * szDataPtr, const char * szDat return NULL; // Give the values - ConvertStringToBinary(szHashString, HashStringLength, HashValue); + BinaryFromString(szHashString, HashStringLength, HashValue); return szDataPtr; } @@ -717,7 +717,7 @@ static DWORD ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) { // If we have manually given build key, override the value if(hs->szBuildKey != NULL) - dwErrCode = ConvertStringToBinary(hs->szBuildKey, MD5_STRING_SIZE, hs->CdnBuildKey.pbData); + dwErrCode = BinaryFromString(hs->szBuildKey, MD5_STRING_SIZE, hs->CdnBuildKey.pbData); return dwErrCode; } @@ -1113,7 +1113,7 @@ static DWORD DownloadFile( } else { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } return dwErrCode; @@ -1489,7 +1489,7 @@ LPBYTE LoadInternalFileToMemory(TCascStorage * hs, PCASC_CKEY_ENTRY pCKeyEntry, } else { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } // Handle errors @@ -1500,7 +1500,7 @@ LPBYTE LoadInternalFileToMemory(TCascStorage * hs, PCASC_CKEY_ENTRY pCKeyEntry, cbFileData = 0; // Set the last error - SetLastError(dwErrCode); + SetCascError(dwErrCode); } // Give the loaded file length @@ -1540,13 +1540,13 @@ LPBYTE LoadFileToMemory(LPCTSTR szFileName, DWORD * pcbFileData) } else { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); cbFileData = 0; } } else { - SetLastError(ERROR_BAD_FORMAT); + SetCascError(ERROR_BAD_FORMAT); cbFileData = 0; assert(false); } diff --git a/dep/CascLib/src/CascFindFile.cpp b/dep/CascLib/src/CascFindFile.cpp index 9694ae5e878..76efa12ae43 100644 --- a/dep/CascLib/src/CascFindFile.cpp +++ b/dep/CascLib/src/CascFindFile.cpp @@ -206,9 +206,13 @@ HANDLE WINAPI CascFindFirstFile( // Check parameters if((hs = TCascStorage::IsValid(hStorage)) == NULL) dwErrCode = ERROR_INVALID_HANDLE; - if(szMask == NULL || pFindData == NULL) + if(pFindData == NULL) dwErrCode = ERROR_INVALID_PARAMETER; + // Supply default mask, if needed + if(szMask == NULL || szMask[0] == 0) + szMask = "*"; + // Init the search structure and search handle if(dwErrCode == ERROR_SUCCESS) { @@ -243,7 +247,7 @@ bool WINAPI CascFindNextFile( pSearch = TCascSearch::IsValid(hFind); if(pSearch == NULL || pFindData == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -258,7 +262,7 @@ bool WINAPI CascFindClose(HANDLE hFind) pSearch = TCascSearch::IsValid(hFind); if(pSearch == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } diff --git a/dep/CascLib/src/CascIndexFiles.cpp b/dep/CascLib/src/CascIndexFiles.cpp index bfcee15330b..bc50f9f25bb 100644 --- a/dep/CascLib/src/CascIndexFiles.cpp +++ b/dep/CascLib/src/CascIndexFiles.cpp @@ -50,8 +50,8 @@ static bool IndexDirectory_OnFileFound( { TCascStorage * hs = (TCascStorage *)pvContext; PCASC_INDEX pIndexFile; - DWORD IndexValue = 0; DWORD IndexVersion = 0; + DWORD IndexValue = 0; // Auto-detect the format of the index file name if(hs->szIndexFormat == NULL) @@ -71,9 +71,9 @@ static bool IndexDirectory_OnFileFound( return false; // Get the main index from the first two digits - if(ConvertStringToInt32(szFileName, 2, &IndexValue) != ERROR_SUCCESS) + if(ConvertStringToInt(szFileName + 0, 2, IndexValue) != ERROR_SUCCESS) return false; - if(ConvertStringToInt32(szFileName + 2, 8, &IndexVersion) != ERROR_SUCCESS) + if(ConvertStringToInt(szFileName + 2, 8, IndexVersion) != ERROR_SUCCESS) return false; } else if(hs->szIndexFormat == szIndexFormat_V1) @@ -83,9 +83,9 @@ static bool IndexDirectory_OnFileFound( return false; // Get the main index from the first two digits - if(ConvertDigitToInt32(szFileName + 6, &IndexValue) != ERROR_SUCCESS) + if(ConvertStringToInt(szFileName + 6, 1, IndexValue) != ERROR_SUCCESS) return false; - if(ConvertDigitToInt32(szFileName + 7, &IndexVersion) != ERROR_SUCCESS) + if(ConvertStringToInt(szFileName + 7, 1, IndexVersion) != ERROR_SUCCESS) return false; } else @@ -316,10 +316,8 @@ static DWORD LoadIndexItems(TCascStorage * hs, CASC_INDEX_HEADER & InHeader, EKE while((pbEKeyEntry + EntryLength) <= pbEKeyEnd) { - // ENCODING, DOWNLOAD, ROOT in Warcraft III Reforged build 14481 - BREAK_ON_XKEY3(pbEKeyEntry, 0xcd, 0x3b, 0xd8); - BREAK_ON_XKEY3(pbEKeyEntry, 0xdb, 0xfa, 0x35); - BREAK_ON_XKEY3(pbEKeyEntry, 0x5c, 0xe8, 0x48); + // ENCODING for Starcraft II Beta + BREAK_ON_XKEY3(pbEKeyEntry, 0x8b, 0x0d, 0x9a); if(!PfnEKeyEntry(hs, InHeader, pbEKeyEntry)) return ERROR_INDEX_PARSING_DONE; @@ -581,7 +579,7 @@ static DWORD LoadLocalIndexFiles(TCascStorage * hs) if((IndexFile.pbFileData = LoadFileToMemory(IndexFile.szFileName, &cbFileData)) == NULL) { // Storages downloaded by Blizzget tool don't have all index files present - if((dwErrCode = GetLastError()) == ERROR_FILE_NOT_FOUND) + if((dwErrCode = GetCascError()) == ERROR_FILE_NOT_FOUND) { dwErrCode = ERROR_SUCCESS; break; diff --git a/dep/CascLib/src/CascLib.h b/dep/CascLib/src/CascLib.h index b9a3ef7de0d..75f8729e75f 100644 --- a/dep/CascLib/src/CascLib.h +++ b/dep/CascLib/src/CascLib.h @@ -369,18 +369,16 @@ bool WINAPI CascFindClose(HANDLE hFind); bool WINAPI CascAddEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPBYTE Key); bool WINAPI CascAddStringEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPCSTR szKey); +bool WINAPI CascImportKeysFromString(HANDLE hStorage, LPCSTR szKeyList); +bool WINAPI CascImportKeysFromFile(HANDLE hStorage, LPCTSTR szFileName); LPBYTE WINAPI CascFindEncryptionKey(HANDLE hStorage, ULONGLONG KeyName); bool WINAPI CascGetNotFoundEncryptionKey(HANDLE hStorage, ULONGLONG * KeyName); //----------------------------------------------------------------------------- -// GetLastError/SetLastError support for non-Windows platform +// Error code support -#ifndef PLATFORM_WINDOWS - -DWORD GetLastError(); -void SetLastError(DWORD dwErrCode); - -#endif // PLATFORM_WINDOWS +void SetCascError(DWORD dwErrCode); +DWORD GetCascError(); #ifdef __cplusplus } // extern "C" diff --git a/dep/CascLib/src/CascOpenFile.cpp b/dep/CascLib/src/CascOpenFile.cpp index 8ff9739d6e3..dd1d5407575 100644 --- a/dep/CascLib/src/CascOpenFile.cpp +++ b/dep/CascLib/src/CascOpenFile.cpp @@ -85,7 +85,7 @@ DWORD TCascFile::OpenFileSpans(LPCTSTR szSpanList) pFileSpan[i].pStream = pStream = FileStream_OpenFile(szSpanList, BASE_PROVIDER_FILE | STREAM_PROVIDER_FLAT); if(pFileSpan[i].pStream == NULL) { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); break; } @@ -215,7 +215,7 @@ bool OpenFileByCKeyEntry(TCascStorage * hs, PCASC_CKEY_ENTRY pCKeyEntry, DWORD d // Handle last error if(dwErrCode != ERROR_SUCCESS) - SetLastError(dwErrCode); + SetCascError(dwErrCode); return (dwErrCode == ERROR_SUCCESS); } @@ -275,7 +275,7 @@ bool OpenLocalFile(LPCTSTR szFileName, DWORD dwOpenFlags, HANDLE * PtrFileHandle // Handle last error if(dwErrCode != ERROR_SUCCESS) - SetLastError(dwErrCode); + SetCascError(dwErrCode); return (dwErrCode == ERROR_SUCCESS); } @@ -318,14 +318,14 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const void * pvFileName, DWORD dwLocal hs = TCascStorage::IsValid(hStorage); if(hs == NULL) { - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } // Validate the other parameters if(PtrFileHandle == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -338,7 +338,7 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const void * pvFileName, DWORD dwLocal szFileName = (const char *)pvFileName; if(szFileName == NULL || szFileName[0] == 0) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -367,7 +367,7 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const void * pvFileName, DWORD dwLocal break; } - SetLastError(ERROR_FILE_NOT_FOUND); + SetCascError(ERROR_FILE_NOT_FOUND); return false; case CASC_OPEN_BY_CKEY: @@ -375,7 +375,7 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const void * pvFileName, DWORD dwLocal // The 'pvFileName' must be a pointer to 16-byte CKey or EKey if(pvFileName == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -388,7 +388,7 @@ bool WINAPI CascOpenFile(HANDLE hStorage, const void * pvFileName, DWORD dwLocal // The 'pvFileName' must be a pointer to 16-byte CKey or EKey if(pvFileName == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -418,7 +418,7 @@ bool WINAPI CascOpenLocalFile(LPCTSTR szFileName, DWORD dwOpenFlags, HANDLE * Pt // Verify parameters if(szFileName == NULL || szFileName[0] == 0 || PtrFileHandle == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -436,7 +436,7 @@ bool WINAPI CascCloseFile(HANDLE hFile) return true; } - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } diff --git a/dep/CascLib/src/CascOpenStorage.cpp b/dep/CascLib/src/CascOpenStorage.cpp index d48ae50342f..00b3797eb68 100644 --- a/dep/CascLib/src/CascOpenStorage.cpp +++ b/dep/CascLib/src/CascOpenStorage.cpp @@ -150,7 +150,7 @@ void * ProbeOutputBuffer(void * pvBuffer, size_t cbLength, size_t cbMinLength, s // Verify the output length if(cbLength < cbMinLength) { - SetLastError(ERROR_INSUFFICIENT_BUFFER); + SetCascError(ERROR_INSUFFICIENT_BUFFER); pvBuffer = NULL; } @@ -519,7 +519,7 @@ static int LoadEncodingManifest(TCascStorage * hs) } else { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } return dwErrCode; @@ -810,7 +810,7 @@ static int LoadInstallManifest(TCascStorage * hs) } else { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } return dwErrCode; @@ -929,7 +929,7 @@ static int LoadBuildManifest(TCascStorage * hs, DWORD dwLocaleMask) } else { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } return dwErrCode; @@ -990,7 +990,7 @@ static bool GetStorageTags(TCascStorage * hs, void * pvStorageInfo, size_t cbSto // Does the storage support tags? if(hs->TagsArray.IsInitialized() == false) { - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return false; } @@ -1274,14 +1274,14 @@ static LPTSTR ParseOpenParams(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs) // The 'szParams' must not be empty if(szParams == NULL || pArgs == NULL || szParams[0] == 0) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return NULL; } // The 'pArgs' must be valid but must not contain 'szLocalPath', 'szCodeName' or 'szRegion' if(pArgs->szLocalPath != NULL || pArgs->szCodeName != NULL || pArgs->szRegion != NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return NULL; } @@ -1321,7 +1321,7 @@ static LPTSTR ParseOpenParams(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs) } else { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); } return szParamsCopy; @@ -1353,7 +1353,7 @@ bool WINAPI CascOpenStorageEx(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs, b // The arguments and the local path must be entered if(pArgs == NULL || pArgs->szLocalPath == NULL || pArgs->szLocalPath[0] == 0) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } } @@ -1382,7 +1382,7 @@ bool WINAPI CascOpenStorageEx(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs, b // Return the result if(dwErrCode != ERROR_SUCCESS) - SetLastError(dwErrCode); + SetCascError(dwErrCode); return (dwErrCode == ERROR_SUCCESS); } @@ -1425,7 +1425,7 @@ bool WINAPI CascGetStorageInfo( hs = TCascStorage::IsValid(hStorage); if(hs == NULL) { - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } @@ -1460,7 +1460,7 @@ bool WINAPI CascGetStorageInfo( return GetStoragePathProduct(hs, pvStorageInfo, cbStorageInfo, pcbLengthNeeded); default: - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -1482,7 +1482,7 @@ bool WINAPI CascCloseStorage(HANDLE hStorage) hs = TCascStorage::IsValid(hStorage); if(hs == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } diff --git a/dep/CascLib/src/CascPort.h b/dep/CascLib/src/CascPort.h index 8a296505c7e..030d12719f4 100644 --- a/dep/CascLib/src/CascPort.h +++ b/dep/CascLib/src/CascPort.h @@ -24,14 +24,8 @@ #if !defined(PLATFORM_DEFINED) && (defined(_WIN32) || defined(_WIN64)) // In MSVC 8.0, there are some functions declared as deprecated. - #if _MSC_VER >= 1400 - #ifndef _CRT_SECURE_NO_DEPRECATE - #define _CRT_SECURE_NO_DEPRECATE - #endif - #ifndef _CRT_NON_CONFORMING_SWPRINTFS - #define _CRT_NON_CONFORMING_SWPRINTFS - #endif - #endif + #define _CRT_SECURE_NO_DEPRECATE + #define _CRT_NON_CONFORMING_SWPRINTFS #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -54,24 +48,14 @@ #include <sys/types.h> #define PLATFORM_LITTLE_ENDIAN - #ifdef _WIN64 - #define PLATFORM_64BIT - #else - #define PLATFORM_32BIT - #endif + #pragma intrinsic(memset, memcmp, memcpy) // Make these functions intrinsic (inline) #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '\\' #define PATH_SEP_STRING "\\" #define PLATFORM_WINDOWS - #define PLATFORM_DEFINED // The platform is known now - -#endif - -#if _MSC_VER >= 1500 - #include <intrin.h> // Support for intrinsic functions - #pragma intrinsic(memcmp, memcpy) + #define PLATFORM_DEFINED // The platform is known now #endif #ifndef FIELD_OFFSET @@ -161,11 +145,6 @@ // Definition of Windows-specific types for non-Windows platforms #ifndef PLATFORM_WINDOWS - #if __LP64__ - #define PLATFORM_64BIT - #else - #define PLATFORM_32BIT - #endif // Typedefs for ANSI C typedef unsigned char BYTE; @@ -188,7 +167,7 @@ typedef TCHAR * LPTSTR; typedef const TCHAR * LPCTSTR; - #ifdef PLATFORM_32BIT + #ifndef __LP64__ #define _LZMA_UINT32_IS_ULONG #endif @@ -254,6 +233,8 @@ #define ERROR_CAN_NOT_COMPLETE 1003 // No such error code under Linux #define ERROR_FILE_CORRUPT 1004 // No such error code under Linux #define ERROR_FILE_ENCRYPTED 1005 // Returned by encrypted stream when can't find file key + #define ERROR_FILE_TOO_LARGE 1006 // No such error code under Linux + #define ERROR_ARITHMETIC_OVERFLOW 1007 // The string value is too large to fit in the given type #endif #ifndef ERROR_FILE_INCOMPLETE diff --git a/dep/CascLib/src/CascReadFile.cpp b/dep/CascLib/src/CascReadFile.cpp index 5bfc4f654a0..6078c32fb7f 100644 --- a/dep/CascLib/src/CascReadFile.cpp +++ b/dep/CascLib/src/CascReadFile.cpp @@ -419,7 +419,7 @@ static DWORD LoadEncodedHeaderAndSpanFrames(PCASC_FILE_SPAN pFileSpan, PCASC_CKE { pbEncodedBuffer = ReadMissingHeaderData(pFileSpan, ReadOffset, pbEncodedBuffer, cbEncodedBuffer, cbTotalHeaderSize); if (pbEncodedBuffer == NULL) - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); cbEncodedBuffer = cbTotalHeaderSize; } @@ -673,7 +673,7 @@ static bool GetFileFullInfo(TCascFile * hf, void * pvFileInfo, size_t cbFileInfo dwErrCode = EnsureFileSpanFramesLoaded(hf); if(dwErrCode != ERROR_SUCCESS) { - SetLastError(dwErrCode); + SetCascError(dwErrCode); return false; } @@ -717,7 +717,7 @@ static bool GetFileSpanInfo(TCascFile * hf, void * pvFileInfo, size_t cbFileInfo dwErrCode = EnsureFileSpanFramesLoaded(hf); if(dwErrCode != ERROR_SUCCESS) { - SetLastError(dwErrCode); + SetCascError(dwErrCode); return false; } @@ -793,7 +793,7 @@ static DWORD ReadFile_WholeFile(TCascFile * hf, LPBYTE pbBuffer) pbEncodedPtr = pbEncoded = CASC_ALLOC<BYTE>(EncodedSize); if(pbEncoded == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); return 0; } @@ -850,7 +850,7 @@ static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG Sta // Check bytes read overflow if((dwBytesRead + pFileFrame->ContentSize) < dwBytesRead) { - SetLastError(ERROR_BUFFER_OVERFLOW); + SetCascError(ERROR_BUFFER_OVERFLOW); return 0; } @@ -861,7 +861,7 @@ static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG Sta { if((pbDecoded = CASC_ALLOC<BYTE>(pFileFrame->ContentSize)) == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); return 0; } bNeedFreeDecoded = true; @@ -876,7 +876,7 @@ static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG Sta if((pbEncoded = CASC_ALLOC<BYTE>(pFileFrame->EncodedSize)) == NULL) { CASC_FREE(pbDecoded); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); return 0; } @@ -933,7 +933,7 @@ static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG Sta pbDecoded = NULL; // Return the number of bytes read. Always set LastError. - SetLastError(dwErrCode); + SetCascError(dwErrCode); return (DWORD)(pbBuffer - pbSaveBuffer); } @@ -968,7 +968,7 @@ bool WINAPI CascGetFileInfo(HANDLE hFile, CASC_FILE_INFO_CLASS InfoClass, void * // Validate the file handle if((hf = TCascFile::IsValid(hFile)) == NULL) { - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } @@ -980,7 +980,7 @@ bool WINAPI CascGetFileInfo(HANDLE hFile, CASC_FILE_INFO_CLASS InfoClass, void * // Do we have content key at all? if(hf->pCKeyEntry == NULL || (hf->pCKeyEntry->Flags & CASC_CE_HAS_CKEY) == 0) { - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return false; } @@ -994,7 +994,7 @@ bool WINAPI CascGetFileInfo(HANDLE hFile, CASC_FILE_INFO_CLASS InfoClass, void * // Do we have content key at all? if(hf->pCKeyEntry == NULL || (hf->pCKeyEntry->Flags & CASC_CE_HAS_EKEY) == 0) { - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return false; } @@ -1010,7 +1010,7 @@ bool WINAPI CascGetFileInfo(HANDLE hFile, CASC_FILE_INFO_CLASS InfoClass, void * return GetFileSpanInfo(hf, pvFileInfo, cbFileInfo, pcbLengthNeeded); default: - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -1050,14 +1050,14 @@ bool WINAPI CascGetFileSize64(HANDLE hFile, PULONGLONG PtrFileSize) // Validate the file handle if((hf = TCascFile::IsValid(hFile)) == NULL) { - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } // Validate the file pointer if(PtrFileSize == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -1066,7 +1066,7 @@ bool WINAPI CascGetFileSize64(HANDLE hFile, PULONGLONG PtrFileSize) dwErrCode = EnsureFileSpanFramesLoaded(hf); if(dwErrCode != ERROR_SUCCESS) { - SetLastError(dwErrCode); + SetCascError(dwErrCode); return false; } @@ -1098,7 +1098,7 @@ bool WINAPI CascSetFilePointer64(HANDLE hFile, LONGLONG DistanceToMove, PULONGLO hf = TCascFile::IsValid(hFile); if(hf == NULL) { - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } @@ -1118,7 +1118,7 @@ bool WINAPI CascSetFilePointer64(HANDLE hFile, LONGLONG DistanceToMove, PULONGLO break; default: - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -1128,7 +1128,7 @@ bool WINAPI CascSetFilePointer64(HANDLE hFile, LONGLONG DistanceToMove, PULONGLO // Do not allow the file pointer to overflow 64-bit range if((FilePosition + DistanceToMove) < FilePosition) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -1142,7 +1142,7 @@ bool WINAPI CascSetFilePointer64(HANDLE hFile, LONGLONG DistanceToMove, PULONGLO // Do not allow the file pointer to underflow 64-bit range if((FilePosition + DistanceToMove) > FilePosition) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } @@ -1190,14 +1190,14 @@ bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDW // The buffer must be valid if(pvBuffer == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return false; } // Validate the file handle if((hf = TCascFile::IsValid(hFile)) == NULL) { - SetLastError(ERROR_INVALID_HANDLE); + SetCascError(ERROR_INVALID_HANDLE); return false; } @@ -1206,7 +1206,7 @@ bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDW dwErrCode = EnsureFileSpanFramesLoaded(hf); if(dwErrCode != ERROR_SUCCESS) { - SetLastError(dwErrCode); + SetCascError(dwErrCode); return false; } diff --git a/dep/CascLib/src/CascRootFile_OW.cpp b/dep/CascLib/src/CascRootFile_OW.cpp index 251a67284cb..b270ec76206 100644 --- a/dep/CascLib/src/CascRootFile_OW.cpp +++ b/dep/CascLib/src/CascRootFile_OW.cpp @@ -502,7 +502,7 @@ struct TRootHandler_OW : public TFileTreeRoot if(FileName.szValue && CKeyStr.szValue && CKeyStr.nLength == MD5_STRING_SIZE) { // Convert the string CKey to binary - if(ConvertStringToBinary(CKeyStr.szValue, MD5_STRING_SIZE, CKey) == ERROR_SUCCESS) + if(BinaryFromString(CKeyStr.szValue, MD5_STRING_SIZE, CKey) == ERROR_SUCCESS) { // Find the item in the tree if((pCKeyEntry = FindCKeyEntry_CKey(hs, CKey)) != NULL) diff --git a/dep/CascLib/src/CascRootFile_Text.cpp b/dep/CascLib/src/CascRootFile_Text.cpp index 7662f85d86d..655080bd2ee 100644 --- a/dep/CascLib/src/CascRootFile_Text.cpp +++ b/dep/CascLib/src/CascRootFile_Text.cpp @@ -67,7 +67,7 @@ struct TRootHandler_SC1 : public TFileTreeRoot const CASC_CSV_COLUMN & CKeyStr = Csv[CSV_ZERO][1]; // Convert the CKey to binary - if(ConvertStringToBinary(CKeyStr.szValue, MD5_STRING_SIZE, CKey) == ERROR_SUCCESS) + if(BinaryFromString(CKeyStr.szValue, MD5_STRING_SIZE, CKey) == ERROR_SUCCESS) { // Verify whether it is a known entry if((pCKeyEntry = FindCKeyEntry_CKey(hs, CKey)) != NULL) diff --git a/dep/CascLib/src/CascRootFile_WoW.cpp b/dep/CascLib/src/CascRootFile_WoW.cpp index 3bbd8b81ef3..dd085b872e7 100644 --- a/dep/CascLib/src/CascRootFile_WoW.cpp +++ b/dep/CascLib/src/CascRootFile_WoW.cpp @@ -413,7 +413,7 @@ struct TRootHandler_WoW : public TFileTreeRoot nLength = ListFile_GetNext(pSearch->pCache, szFileName, _countof(szFileName), &FileDataId); if(nLength == 0) { - if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + if(GetCascError() == ERROR_INSUFFICIENT_BUFFER) continue; break; } @@ -435,7 +435,7 @@ struct TRootHandler_WoW : public TFileTreeRoot nLength = ListFile_GetNextLine(pSearch->pCache, szFileName, _countof(szFileName)); if(nLength == 0) { - if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + if(GetCascError() == ERROR_INSUFFICIENT_BUFFER) continue; break; } diff --git a/dep/CascLib/src/CascLib.def b/dep/CascLib/src/DllMain.def index 9442184946f..9442184946f 100644 --- a/dep/CascLib/src/CascLib.def +++ b/dep/CascLib/src/DllMain.def diff --git a/dep/CascLib/src/DllMain.rc b/dep/CascLib/src/DllMain.rc index 7007a24ab65..4241c2687de 100644 --- a/dep/CascLib/src/DllMain.rc +++ b/dep/CascLib/src/DllMain.rc @@ -1,4 +1,6 @@ // Microsoft Visual C++ generated resource script. +// +#include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -25,8 +27,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,50,0,197 - PRODUCTVERSION 1,50,0,197 + FILEVERSION 1,50,0,204 + PRODUCTVERSION 1,50,0,204 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -41,13 +43,14 @@ BEGIN BEGIN BLOCK "040504b0" BEGIN + VALUE "Comments", "http://www.zezula.net/casc.html" VALUE "FileDescription", "CascLib library for reading Blizzard CASC storages" - VALUE "FileVersion", "1, 50, 0, 197\0" + VALUE "FileVersion", "1, 50, 0, 204\0" VALUE "InternalName", "CascLib" VALUE "LegalCopyright", "Copyright (c) 2014 - 2019 Ladislav Zezula" VALUE "OriginalFilename", "CascLib.dll" VALUE "ProductName", "CascLib" - VALUE "ProductVersion", "1, 50, 0, 197\0" + VALUE "ProductVersion", "1, 50, 0, 204\0" END END BLOCK "VarFileInfo" @@ -75,18 +78,23 @@ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT // TEXTINCLUDE // -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" END +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + #endif // APSTUDIO_INVOKED #endif // Czech resources diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp index c16323e0f5e..7bec2b14a6a 100644 --- a/dep/CascLib/src/common/Common.cpp +++ b/dep/CascLib/src/common/Common.cpp @@ -59,24 +59,42 @@ unsigned char AsciiToUpperTable_BkSlash[256] = 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; +// Converts ASCII characters to hexa digit +unsigned char AsciiToHexTable[128] = +{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + unsigned char IntToHexChar[] = "0123456789abcdef"; //----------------------------------------------------------------------------- -// GetLastError/SetLastError support for non-Windows platform +// GetCascError/SetCascError support for non-Windows platform -#ifndef PLATFORM_WINDOWS static DWORD dwLastError = ERROR_SUCCESS; -DWORD GetLastError() +DWORD GetCascError() { +#ifdef PLATFORM_WINDOWS + return GetLastError(); +#else return dwLastError; +#endif } -void SetLastError(DWORD dwErrCode) +void SetCascError(DWORD dwErrCode) { +#ifdef PLATFORM_WINDOWS + SetLastError(dwErrCode); +#endif dwLastError = dwErrCode; } -#endif //----------------------------------------------------------------------------- // Linear data stream manipulation @@ -520,103 +538,6 @@ ULONGLONG CalcFileNameHash(const char * szFileName) return CalcNormNameHash(szNormName, nLength); } -DWORD ConvertDigitToInt32(LPCTSTR szString, PDWORD PtrValue) -{ - BYTE Digit; - - Digit = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - _T('0')); - if(Digit > 9) - Digit -= 'A' - '9' - 1; - - PtrValue[0] = Digit; - return (Digit > 0x0F) ? ERROR_BAD_FORMAT : ERROR_SUCCESS; -} - -DWORD ConvertStringToInt08(LPCSTR szString, PDWORD PtrValue) -{ - BYTE DigitOne = AsciiToUpperTable_BkSlash[szString[0]] - '0'; - BYTE DigitTwo = AsciiToUpperTable_BkSlash[szString[1]] - '0'; - - // Fix the digits - if(DigitOne > 9) - DigitOne -= 'A' - '9' - 1; - if(DigitTwo > 9) - DigitTwo -= 'A' - '9' - 1; - - // Combine them into a value - PtrValue[0] = (DigitOne << 0x04) | DigitTwo; - return (DigitOne <= 0x0F && DigitTwo <= 0x0F) ? ERROR_SUCCESS : ERROR_BAD_FORMAT; -} - -DWORD ConvertStringToInt32(LPCTSTR szString, size_t nMaxDigits, PDWORD PtrValue) -{ - // The number of digits must be even - assert((nMaxDigits & 0x01) == 0); - assert(nMaxDigits <= 8); - - // Prepare the variables - PtrValue[0] = 0; - nMaxDigits >>= 1; - - // Convert the string up to the number of digits - for(size_t i = 0; i < nMaxDigits; i++) - { - BYTE DigitOne; - BYTE DigitTwo; - - DigitOne = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - _T('0')); - if(DigitOne > 9) - DigitOne -= 'A' - '9' - 1; - - DigitTwo = (BYTE)(AsciiToUpperTable_BkSlash[szString[1]] - _T('0')); - if(DigitTwo > 9) - DigitTwo -= 'A' - '9' - 1; - - if(DigitOne > 0x0F || DigitTwo > 0x0F) - return ERROR_BAD_FORMAT; - - PtrValue[0] = (PtrValue[0] << 0x08) | (DigitOne << 0x04) | DigitTwo; - szString += 2; - } - - return ERROR_SUCCESS; -} - -// Converts string blob to binary blob. -DWORD ConvertStringToBinary( - LPCSTR szString, - size_t nMaxDigits, - LPBYTE pbBinary) -{ - const char * szStringEnd = szString + nMaxDigits; - DWORD dwCounter = 0; - BYTE DigitValue; - BYTE ByteValue = 0; - - // Convert the string - while(szString < szStringEnd) - { - // Retrieve the digit converted to hexa - DigitValue = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - '0'); - if(DigitValue > 9) - DigitValue -= 'A' - '9' - 1; - if(DigitValue > 0x0F) - return ERROR_BAD_FORMAT; - - // Insert the digit to the binary buffer - ByteValue = (ByteValue << 0x04) | DigitValue; - dwCounter++; - - // If we reached the second digit, it means that we need - // to flush the byte value and move on - if((dwCounter & 0x01) == 0) - *pbBinary++ = ByteValue; - szString++; - } - - return ERROR_SUCCESS; -} - //----------------------------------------------------------------------------- // File name utilities @@ -648,7 +569,7 @@ bool IsFileDataIdName(const char * szFileName, DWORD & FileDataId) if(!strncmp(szFileName, "FILE", 4) && strlen(szFileName) >= 0x0C) { // Convert the hexadecimal number to integer - if(ConvertStringToBinary(szFileName+4, 8, BinaryValue) == ERROR_SUCCESS) + if(BinaryFromString(szFileName+4, 8, BinaryValue) == ERROR_SUCCESS) { // Must be followed by an extension or end-of-string if(szFileName[0x0C] == 0 || szFileName[0x0C] == '.') @@ -668,7 +589,7 @@ bool IsFileCKeyEKeyName(const char * szFileName, LPBYTE PtrKeyBuffer) if(nLength == MD5_STRING_SIZE) { - if(ConvertStringToBinary(szFileName, MD5_STRING_SIZE, PtrKeyBuffer) == ERROR_SUCCESS) + if(BinaryFromString(szFileName, MD5_STRING_SIZE, PtrKeyBuffer) == ERROR_SUCCESS) { return true; } diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h index 0037293f53d..46b23adb6ae 100644 --- a/dep/CascLib/src/common/Common.h +++ b/dep/CascLib/src/common/Common.h @@ -124,6 +124,7 @@ typedef CASC_CKEY_ENTRY *PCASC_CKEY_ENTRY; extern unsigned char AsciiToLowerTable_Slash[256]; extern unsigned char AsciiToUpperTable_BkSlash[256]; +extern unsigned char AsciiToHexTable[0x80]; extern unsigned char IntToHexChar[]; //----------------------------------------------------------------------------- @@ -339,15 +340,82 @@ size_t NormalizeFileName_LowerSlash(char * szNormName, const char * szFileName, ULONGLONG CalcNormNameHash(const char * szNormName, size_t nLength); ULONGLONG CalcFileNameHash(const char * szFileName); -DWORD ConvertDigitToInt32(LPCTSTR szString, PDWORD PtrValue); -DWORD ConvertStringToInt08(LPCSTR szString, PDWORD PtrValue); -DWORD ConvertStringToInt32(LPCTSTR szString, size_t nMaxDigits, PDWORD PtrValue); -DWORD ConvertStringToBinary(LPCSTR szString, size_t nMaxDigits, LPBYTE pbBinary); - //----------------------------------------------------------------------------- -// Conversion from binary array to string. The caller must ensure that -// the buffer has at least ((cbBinary * 2) + 1) characters +// String conversion functions + +template <typename xchar, typename INTXX> +DWORD ConvertStringToInt(const xchar * szString, size_t nMaxDigits, INTXX & RefValue, const xchar ** PtrStringEnd = NULL) +{ + INTXX MaxValueMask = (INTXX)0x0F << ((sizeof(INTXX) * 8) - 4); + INTXX Accumulator = 0; + BYTE DigitOne; + + // Set default value + if(nMaxDigits == 0) + nMaxDigits = sizeof(INTXX) * 2; + + // Convert the string up to the number of digits + for(size_t i = 0; i < nMaxDigits; i++, szString++) + { + // Check for the end of the string + if(szString[0] > sizeof(AsciiToHexTable)) + return ERROR_BAD_FORMAT; + if(szString[0] <= 0x20) + break; + + // Extract the next digit + DigitOne = AsciiToHexTable[szString[0]]; + if(DigitOne == 0xFF) + return ERROR_BAD_FORMAT; + + // Check overflow. If OK, shift the value by 4 to the left + if(Accumulator & MaxValueMask) + return ERROR_ARITHMETIC_OVERFLOW; + Accumulator = (Accumulator << 4) | DigitOne; + } + + // Give the results + if(PtrStringEnd != NULL) + PtrStringEnd[0] = szString; + RefValue = Accumulator; + return ERROR_SUCCESS; +} + +// Converts string blob to binary blob +template <typename xchar> +DWORD BinaryFromString(const xchar * szString, size_t nMaxDigits, LPBYTE pbBinary) +{ + const xchar * szStringEnd = szString + nMaxDigits; + DWORD dwCounter = 0; + BYTE DigitValue; + BYTE ByteValue = 0; + + // Convert the string + while(szString < szStringEnd) + { + // Retrieve the digit converted to hexa + DigitValue = (BYTE)(AsciiToUpperTable_BkSlash[szString[0]] - '0'); + if(DigitValue > 9) + DigitValue -= 'A' - '9' - 1; + if(DigitValue > 0x0F) + return ERROR_BAD_FORMAT; + + // Insert the digit to the binary buffer + ByteValue = (ByteValue << 0x04) | DigitValue; + dwCounter++; + + // If we reached the second digit, it means that we need + // to flush the byte value and move on + if((dwCounter & 0x01) == 0) + *pbBinary++ = ByteValue; + szString++; + } + + return ERROR_SUCCESS; +} +// Converts binary array to string. +// The caller must ensure that the buffer has at least ((cbBinary * 2) + 1) characters template <typename xchar> xchar * StringFromBinary(LPBYTE pbBinary, size_t cbBinary, xchar * szBuffer) { diff --git a/dep/CascLib/src/common/Csv.cpp b/dep/CascLib/src/common/Csv.cpp index 818973e9603..40a50ec723b 100644 --- a/dep/CascLib/src/common/Csv.cpp +++ b/dep/CascLib/src/common/Csv.cpp @@ -203,7 +203,7 @@ DWORD CASC_CSV::Load(LPCTSTR szFileName) } else { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } return dwErrCode; diff --git a/dep/CascLib/src/common/FileStream.cpp b/dep/CascLib/src/common/FileStream.cpp index 350b0540cf4..cb0090f8dfb 100644 --- a/dep/CascLib/src/common/FileStream.cpp +++ b/dep/CascLib/src/common/FileStream.cpp @@ -75,7 +75,7 @@ static bool BaseFile_Create(TFileStream * pStream) if(handle == -1) { pStream->Base.File.hFile = INVALID_HANDLE_VALUE; - SetLastError(errno); + SetCascError(errno); return false; } @@ -128,14 +128,14 @@ static bool BaseFile_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStr handle = open(szFileName, oflag | O_LARGEFILE); if(handle == -1) { - SetLastError(errno); + SetCascError(errno); return false; } // Get the file size if(fstat64(handle, &fileinfo) == -1) { - SetLastError(errno); + SetCascError(errno); close(handle); return false; } @@ -185,8 +185,11 @@ static bool BaseFile_Read( Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); Overlapped.Offset = (DWORD)ByteOffset; Overlapped.hEvent = NULL; - if (!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped)) + if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped)) + { + CascUnlock(pStream->Lock); return false; + } } } #endif @@ -201,7 +204,8 @@ static bool BaseFile_Read( { if (lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) { - SetLastError(errno); + CascUnlock(pStream->Lock); + SetCascError(errno); return false; } pStream->Base.File.FilePos = ByteOffset; @@ -213,7 +217,8 @@ static bool BaseFile_Read( bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead); if (bytes_read == -1) { - SetLastError(errno); + CascUnlock(pStream->Lock); + SetCascError(errno); return false; } @@ -239,7 +244,7 @@ static bool BaseFile_Read( } else { - SetLastError(ERROR_HANDLE_EOF); + SetCascError(ERROR_HANDLE_EOF); } } @@ -280,8 +285,11 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); Overlapped.Offset = (DWORD)ByteOffset; Overlapped.hEvent = NULL; - if (!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped)) + if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped)) + { + CascUnlock(pStream->Lock); return false; + } } } #endif @@ -296,7 +304,8 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const { if (lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) { - SetLastError(errno); + CascUnlock(pStream->Lock); + SetCascError(errno); return false; } pStream->Base.File.FilePos = ByteOffset; @@ -306,7 +315,8 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite); if (bytes_written == -1) { - SetLastError(errno); + CascUnlock(pStream->Lock); + SetCascError(errno); return false; } @@ -324,7 +334,7 @@ static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const CascUnlock(pStream->Lock); if(dwBytesWritten != dwBytesToWrite) - SetLastError(ERROR_DISK_FULL); + SetCascError(ERROR_DISK_FULL); return (dwBytesWritten == dwBytesToWrite); } @@ -343,7 +353,7 @@ static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize) // Set the position at the new file size dwNewPos = SetFilePointer(pStream->Base.File.hFile, (LONG)NewFileSize, &FileSizeHi, FILE_BEGIN); - if(dwNewPos == INVALID_SET_FILE_POINTER && GetLastError() != ERROR_SUCCESS) + if(dwNewPos == INVALID_SET_FILE_POINTER && GetCascError() != ERROR_SUCCESS) return false; // Set the current file pointer as the end of the file @@ -363,7 +373,7 @@ static bool BaseFile_Resize(TFileStream * pStream, ULONGLONG NewFileSize) { if(ftruncate64((intptr_t)pStream->Base.File.hFile, (off64_t)NewFileSize) == -1) { - SetLastError(errno); + SetCascError(errno); return false; } @@ -403,7 +413,7 @@ static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream) // "rename" on Linux also works if the target file exists if(rename(pNewStream->szFileName, pStream->szFileName) == -1) { - SetLastError(errno); + SetCascError(errno); return false; } @@ -533,7 +543,7 @@ static bool BaseMap_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStre // Did the mapping fail? if(bResult == false) { - SetLastError(errno); + SetCascError(errno); return false; } #endif @@ -638,7 +648,7 @@ static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStr // Don't download if we are not connected to the internet if(!InternetGetConnectedState(&dwTemp, 0)) - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); // Initiate the connection to the internet if(dwErrCode == ERROR_SUCCESS) @@ -649,7 +659,7 @@ static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStr NULL, 0); if(pStream->Base.Http.hInternet == NULL) - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } // Connect to the server @@ -669,7 +679,7 @@ static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStr dwFlags, 0); if(pStream->Base.Http.hConnect == NULL) - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); } // Now try to query the file size @@ -727,7 +737,7 @@ static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStr if(bFileAvailable == false) { pStream->BaseClose(pStream); - SetLastError(dwErrCode); + SetCascError(dwErrCode); return false; } @@ -736,7 +746,7 @@ static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStr #else // Not supported - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); pStream = pStream; return false; @@ -804,7 +814,7 @@ static bool BaseHttp_Read( // If the number of bytes read doesn't match the required amount, return false if(dwTotalBytesRead != dwBytesToRead) - SetLastError(ERROR_HANDLE_EOF); + SetCascError(ERROR_HANDLE_EOF); return (dwTotalBytesRead == dwBytesToRead); #else @@ -814,7 +824,7 @@ static bool BaseHttp_Read( pByteOffset = pByteOffset; pvBuffer = pvBuffer; dwBytesToRead = dwBytesToRead; - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return false; #endif @@ -888,7 +898,7 @@ static bool BlockStream_Read( EndOffset = ByteOffset + dwBytesToRead; if(EndOffset > pStream->StreamSize) { - SetLastError(ERROR_HANDLE_EOF); + SetCascError(ERROR_HANDLE_EOF); return false; } @@ -905,7 +915,7 @@ static bool BlockStream_Read( TransferBuffer = BlockBuffer = CASC_ALLOC<BYTE>(BlockCount * BlockSize); if(TransferBuffer == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); return false; } @@ -983,7 +993,7 @@ static bool BlockStream_Read( else { // If the block read failed, set the last error - SetLastError(ERROR_FILE_INCOMPLETE); + SetCascError(ERROR_FILE_INCOMPLETE); } // Call the callback to indicate we are done @@ -1058,7 +1068,7 @@ static TFileStream * AllocateFileStream( // Don't allow another master file in the string if(_tcschr(szNextFile + 1, _T('*')) != NULL) { - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return NULL; } @@ -1392,7 +1402,7 @@ static TFileStream * FlatStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) pStream = (TBlockStream *)AllocateFileStream(szFileName, sizeof(TBlockStream), dwStreamFlags); if(pStream == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } @@ -1402,7 +1412,7 @@ static TFileStream * FlatStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) if(!FlatStream_CreateMirror(pStream)) { FileStream_Close(pStream); - SetLastError(ERROR_FILE_NOT_FOUND); + SetCascError(ERROR_FILE_NOT_FOUND); return NULL; } } @@ -1819,7 +1829,7 @@ static TFileStream * PartStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) if(!PartStream_CreateMirror(pStream)) { FileStream_Close(pStream); - SetLastError(ERROR_FILE_NOT_FOUND); + SetCascError(ERROR_FILE_NOT_FOUND); return NULL; } } @@ -1836,7 +1846,7 @@ static TFileStream * PartStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) if(!PartStream_LoadBitmap(pStream)) { FileStream_Close(pStream); - SetLastError(ERROR_BAD_FORMAT); + SetCascError(ERROR_BAD_FORMAT); return NULL; } } @@ -2149,7 +2159,7 @@ static TFileStream * EncrStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) // Cleanup the stream and return FileStream_Close(pStream); - SetLastError(ERROR_FILE_ENCRYPTED); + SetCascError(ERROR_FILE_ENCRYPTED); return NULL; } @@ -2293,7 +2303,7 @@ static TFileStream * Block4Stream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) NewBaseArray = CASC_ALLOC<TBaseProviderData>(dwBaseFiles + 1); if(NewBaseArray == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + SetCascError(ERROR_NOT_ENOUGH_MEMORY); return NULL; } @@ -2348,7 +2358,7 @@ static TFileStream * Block4Stream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) if(dwBaseFiles == 0) { FileStream_Close(pStream); - SetLastError(ERROR_FILE_NOT_FOUND); + SetCascError(ERROR_FILE_NOT_FOUND); pStream = NULL; } @@ -2384,7 +2394,7 @@ TFileStream * FileStream_CreateFile( // We only support creation of flat, local file if((dwStreamFlags & (STREAM_PROVIDERS_MASK)) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE)) { - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return NULL; } @@ -2457,7 +2467,7 @@ TFileStream * FileStream_OpenFile( return Block4Stream_Open(szFileName, dwStreamFlags); default: - SetLastError(ERROR_INVALID_PARAMETER); + SetCascError(ERROR_INVALID_PARAMETER); return NULL; } } @@ -2569,7 +2579,7 @@ bool FileStream_SetCallback(TFileStream * pStream, STREAM_DOWNLOAD_CALLBACK pfnC if(pStream->BlockRead == NULL) { - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return false; } @@ -2594,8 +2604,8 @@ bool FileStream_SetCallback(TFileStream * pStream, STREAM_DOWNLOAD_CALLBACK pfnC * * \returns * - If the function reads the required amount of bytes, it returns true. - * - If the function reads less than required bytes, it returns false and GetLastError() returns ERROR_HANDLE_EOF - * - If the function fails, it reads false and GetLastError() returns an error code different from ERROR_HANDLE_EOF + * - If the function reads less than required bytes, it returns false and GetCascError() returns ERROR_HANDLE_EOF + * - If the function fails, it reads false and GetCascError() returns an error code different from ERROR_HANDLE_EOF */ bool FileStream_Read(TFileStream * pStream, ULONGLONG * pByteOffset, void * pvBuffer, DWORD dwBytesToRead) { @@ -2619,7 +2629,7 @@ bool FileStream_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void { if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) { - SetLastError(ERROR_ACCESS_DENIED); + SetCascError(ERROR_ACCESS_DENIED); return false; } @@ -2649,7 +2659,7 @@ bool FileStream_SetSize(TFileStream * pStream, ULONGLONG NewFileSize) { if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) { - SetLastError(ERROR_ACCESS_DENIED); + SetCascError(ERROR_ACCESS_DENIED); return false; } @@ -2709,14 +2719,14 @@ bool FileStream_Replace(TFileStream * pStream, TFileStream * pNewStream) // Only supported on flat files if((pStream->dwFlags & STREAM_PROVIDERS_MASK) != (STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE)) { - SetLastError(ERROR_NOT_SUPPORTED); + SetCascError(ERROR_NOT_SUPPORTED); return false; } // Not supported on read-only streams if(pStream->dwFlags & STREAM_FLAG_READ_ONLY) { - SetLastError(ERROR_ACCESS_DENIED); + SetCascError(ERROR_ACCESS_DENIED); return false; } diff --git a/dep/CascLib/src/common/ListFile.cpp b/dep/CascLib/src/common/ListFile.cpp index a284ef2db10..a91922cd9b1 100644 --- a/dep/CascLib/src/common/ListFile.cpp +++ b/dep/CascLib/src/common/ListFile.cpp @@ -245,7 +245,7 @@ size_t ListFile_GetNextLine(void * pvListFile, char * szBuffer, size_t nMaxChars // If we didn't read anything, set the error code if(nLength == 0) - SetLastError(dwErrCode); + SetCascError(dwErrCode); return nLength; } @@ -282,7 +282,7 @@ size_t ListFile_GetNext(void * pvListFile, char * szBuffer, size_t nMaxChars, PD nLength = ListFile_GetNextLine(pvListFile, szBuffer, nMaxChars); if(nLength == 0) { - dwErrCode = GetLastError(); + dwErrCode = GetCascError(); break; } @@ -292,7 +292,7 @@ size_t ListFile_GetNext(void * pvListFile, char * szBuffer, size_t nMaxChars, PD } if(dwErrCode != ERROR_SUCCESS) - SetLastError(dwErrCode); + SetCascError(dwErrCode); return nLength; } diff --git a/dep/CascLib/src/common/Map.h b/dep/CascLib/src/common/Map.h index 4b277cb73a8..54dda5baed8 100644 --- a/dep/CascLib/src/common/Map.h +++ b/dep/CascLib/src/common/Map.h @@ -354,4 +354,27 @@ class CASC_MAP // Will improve performance, as we will not hash a hash :-) }; +//----------------------------------------------------------------------------- +// Key map interface + +// Maximum length of encryption key +#define CASC_KEY_LENGTH 0x10 +#define CASC_KEY_TABLE_SIZE 0x100 +#define CASC_KEY_TABLE_MASK (CASC_KEY_TABLE_SIZE - 1) + +class CASC_KEY_MAP +{ + public: + + CASC_KEY_MAP(); + ~CASC_KEY_MAP(); + + LPBYTE FindKey(ULONGLONG KeyName); + bool AddKey(ULONGLONG KeyName, LPBYTE Key); + + protected: + + void * HashTable[CASC_KEY_TABLE_SIZE]; +}; + #endif // __CASC_MAP_H__ |