mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Dep/CascLib: Update to ladislav-zezula/CascLib@737a8705b5
This commit is contained in:
@@ -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.
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
PCASC_ENCRYPTION_KEY pKey;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Key map implementation
|
||||
|
||||
pKey = (PCASC_ENCRYPTION_KEY)hs->EncryptionKeys.FindObject(&KeyName);
|
||||
return (pKey != NULL) ? pKey->Key : NULL;
|
||||
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_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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// Insert all static keys
|
||||
for (size_t i = 0; i < nKeyCount; i++)
|
||||
hs->EncryptionKeys.InsertObject(&CascKeys[i], &CascKeys[i].KeyName);
|
||||
bool WINAPI CascAddEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPBYTE Key)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
|
||||
// Create array for extra keys
|
||||
dwErrCode = hs->ExtraKeysList.Create<CASC_ENCRYPTION_KEY>(CASC_EXTRA_KEYS);
|
||||
return dwErrCode;
|
||||
// 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);
|
||||
}
|
||||
|
||||
LPBYTE WINAPI CascFindEncryptionKey(HANDLE hStorage, ULONGLONG KeyName)
|
||||
{
|
||||
TCascStorage * hs;
|
||||
|
||||
// Validate the storage handle
|
||||
hs = TCascStorage::IsValid(hStorage);
|
||||
if (hs == NULL)
|
||||
{
|
||||
SetCascError(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -203,7 +203,7 @@ DWORD CASC_CSV::Load(LPCTSTR szFileName)
|
||||
}
|
||||
else
|
||||
{
|
||||
dwErrCode = GetLastError();
|
||||
dwErrCode = GetCascError();
|
||||
}
|
||||
|
||||
return dwErrCode;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -62,7 +62,7 @@ recastnavigation (Recast is state of the art navigation mesh construction toolse
|
||||
|
||||
CascLib (An open-source implementation of library for reading CASC storage from Blizzard games since 2014)
|
||||
https://github.com/ladislav-zezula/CascLib
|
||||
Version: 0a05c59eb8a3eab1bc5471f43934cd5f992f0aca
|
||||
Version: 737a8705b5b8f7ce3917f5d5ff9767b18de1285e
|
||||
|
||||
rapidjson (A fast JSON parser/generator for C++ with both SAX/DOM style API http://rapidjson.org/)
|
||||
https://github.com/miloyip/rapidjson
|
||||
|
||||
@@ -63,10 +63,10 @@ CASC::Storage* CASC::Storage::Open(boost::filesystem::path const& path, uint32 l
|
||||
HANDLE handle = nullptr;
|
||||
if (!::CascOpenStorageEx(nullptr, &args, false, &handle))
|
||||
{
|
||||
DWORD lastError = GetLastError(); // support checking error set by *Open* call, not the next *Close*
|
||||
DWORD lastError = GetCascError(); // support checking error set by *Open* call, not the next *Close*
|
||||
printf("Error opening casc storage '%s': %s\n", path.string().c_str(), HumanReadableCASCError(lastError));
|
||||
CascCloseStorage(handle);
|
||||
SetLastError(lastError);
|
||||
SetCascError(lastError);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -116,12 +116,12 @@ CASC::File* CASC::Storage::OpenFile(char const* fileName, uint32 localeMask, boo
|
||||
HANDLE handle = nullptr;
|
||||
if (!::CascOpenFile(_handle, fileName, localeMask, openFlags, &handle))
|
||||
{
|
||||
DWORD lastError = GetLastError(); // support checking error set by *Open* call, not the next *Close*
|
||||
DWORD lastError = GetCascError(); // support checking error set by *Open* call, not the next *Close*
|
||||
if (printErrors)
|
||||
fprintf(stderr, "Failed to open '%s' in CASC storage: %s\n", fileName, HumanReadableCASCError(lastError));
|
||||
|
||||
CascCloseFile(handle);
|
||||
SetLastError(lastError);
|
||||
SetCascError(lastError);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -137,12 +137,12 @@ CASC::File* CASC::Storage::OpenFile(uint32 fileDataId, uint32 localeMask, bool p
|
||||
HANDLE handle = nullptr;
|
||||
if (!::CascOpenFile(_handle, CASC_FILE_DATA_ID(fileDataId), localeMask, openFlags, &handle))
|
||||
{
|
||||
DWORD lastError = GetLastError(); // support checking error set by *Open* call, not the next *Close*
|
||||
DWORD lastError = GetCascError(); // support checking error set by *Open* call, not the next *Close*
|
||||
if (printErrors)
|
||||
fprintf(stderr, "Failed to open 'FileDataId %u' in CASC storage: %s\n", fileDataId, HumanReadableCASCError(lastError));
|
||||
|
||||
CascCloseFile(handle);
|
||||
SetLastError(lastError);
|
||||
SetCascError(lastError);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ void TryLoadDB2(char const* name, DB2CascFileSource* source, DB2FileLoader* db2,
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
printf("Fatal error: Invalid %s file format! %s\n%s\n", name, CASC::HumanReadableCASCError(GetLastError()), e.what());
|
||||
printf("Fatal error: Invalid %s file format! %s\n%s\n", name, CASC::HumanReadableCASCError(GetCascError()), e.what());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -1215,7 +1215,7 @@ bool ExtractDB2File(uint32 fileDataId, char const* cascFileName, int locale, boo
|
||||
DB2CascFileSource source(CascStorage, fileDataId, false);
|
||||
if (!source.IsOpen())
|
||||
{
|
||||
printf("Unable to open file %s in the archive for locale %s: %s\n", cascFileName, localeNames[locale], CASC::HumanReadableCASCError(GetLastError()));
|
||||
printf("Unable to open file %s in the archive for locale %s: %s\n", cascFileName, localeNames[locale], CASC::HumanReadableCASCError(GetCascError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1351,7 +1351,7 @@ void ExtractCameraFiles()
|
||||
++count;
|
||||
}
|
||||
else
|
||||
printf("Unable to open file %u in the archive: %s\n", cameraFileDataId, CASC::HumanReadableCASCError(GetLastError()));
|
||||
printf("Unable to open file %u in the archive: %s\n", cameraFileDataId, CASC::HumanReadableCASCError(GetCascError()));
|
||||
}
|
||||
|
||||
printf("Extracted %u camera files\n", count);
|
||||
@@ -1407,7 +1407,7 @@ void ExtractGameTables()
|
||||
++count;
|
||||
}
|
||||
else
|
||||
printf("Unable to open file %s in the archive: %s\n", gt.Name, CASC::HumanReadableCASCError(GetLastError()));
|
||||
printf("Unable to open file %s in the archive: %s\n", gt.Name, CASC::HumanReadableCASCError(GetCascError()));
|
||||
}
|
||||
|
||||
printf("Extracted %u files\n\n", count);
|
||||
|
||||
@@ -28,8 +28,8 @@ CASCFile::CASCFile(std::shared_ptr<CASC::Storage const> casc, const char* filena
|
||||
std::unique_ptr<CASC::File> file(casc->OpenFile(filename, CASC_LOCALE_ALL_WOW, false));
|
||||
if (!file)
|
||||
{
|
||||
if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
fprintf(stderr, "Can't open %s: %s\n", filename, CASC::HumanReadableCASCError(GetLastError()));
|
||||
if (warnNoExist || GetCascError() != ERROR_FILE_NOT_FOUND)
|
||||
fprintf(stderr, "Can't open %s: %s\n", filename, CASC::HumanReadableCASCError(GetCascError()));
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
@@ -46,8 +46,8 @@ CASCFile::CASCFile(std::shared_ptr<CASC::Storage const> casc, uint32 fileDataId,
|
||||
std::unique_ptr<CASC::File> file(casc->OpenFile(fileDataId, CASC_LOCALE_ALL_WOW, false));
|
||||
if (!file)
|
||||
{
|
||||
if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
fprintf(stderr, "Can't open %s: %s\n", description.c_str(), CASC::HumanReadableCASCError(GetLastError()));
|
||||
if (warnNoExist || GetCascError() != ERROR_FILE_NOT_FOUND)
|
||||
fprintf(stderr, "Can't open %s: %s\n", description.c_str(), CASC::HumanReadableCASCError(GetCascError()));
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ void CASCFile::init(CASC::File* file, const char* description)
|
||||
int64 fileSize = file->GetSize();
|
||||
if (fileSize == -1)
|
||||
{
|
||||
fprintf(stderr, "Can't open %s, failed to get size: %s!\n", description, CASC::HumanReadableCASCError(GetLastError()));
|
||||
fprintf(stderr, "Can't open %s, failed to get size: %s!\n", description, CASC::HumanReadableCASCError(GetCascError()));
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ void CASCFile::init(CASC::File* file, const char* description)
|
||||
buffer = new char[size];
|
||||
if (!file->ReadFile(buffer, size, &read) || size != read)
|
||||
{
|
||||
fprintf(stderr, "Can't read %s, size=%u read=%u: %s\n", description, uint32(size), uint32(read), CASC::HumanReadableCASCError(GetLastError()));
|
||||
fprintf(stderr, "Can't read %s, size=%u read=%u: %s\n", description, uint32(size), uint32(read), CASC::HumanReadableCASCError(GetCascError()));
|
||||
eof = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ int main(int argc, char ** argv)
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
printf("Fatal error: Invalid Map.db2 file format! %s\n%s\n", CASC::HumanReadableCASCError(GetLastError()), e.what());
|
||||
printf("Fatal error: Invalid Map.db2 file format! %s\n%s\n", CASC::HumanReadableCASCError(GetCascError()), e.what());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user