diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-09-05 00:10:35 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-09-05 00:10:35 +0200 |
commit | d57b58849bda868f2463d38cc636f01af919316c (patch) | |
tree | 5beef62c041526d9468683e4388b6341f1530cc1 /dep/CascLib/src/common | |
parent | ba224f70ad81fa0e5d1f0c4daf197e143317cdaa (diff) |
Dep/CascLib: Update to ladislav-zezula/CascLib@5c60050770767f2e606f6fec0c35beb8b9b00c60
Diffstat (limited to 'dep/CascLib/src/common')
-rw-r--r-- | dep/CascLib/src/common/Array.h | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.cpp | 32 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.h | 83 | ||||
-rw-r--r-- | dep/CascLib/src/common/FileTree.cpp | 19 | ||||
-rw-r--r-- | dep/CascLib/src/common/FileTree.h | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/Map.h | 21 | ||||
-rw-r--r-- | dep/CascLib/src/common/RootHandler.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/RootHandler.h | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/Sockets.cpp | 9 |
9 files changed, 97 insertions, 75 deletions
diff --git a/dep/CascLib/src/common/Array.h b/dep/CascLib/src/common/Array.h index 56cdf073a33..8bd7dc177b9 100644 --- a/dep/CascLib/src/common/Array.h +++ b/dep/CascLib/src/common/Array.h @@ -211,7 +211,7 @@ class CASC_ARRAY while (ItemCountMax < NewItemCount) ItemCountMax = ItemCountMax << 1; - // Allocate new table + // Allocate new table. If this fails, the 'm_pItemArray' remains valid NewItemArray = CASC_REALLOC(m_pItemArray, (ItemCountMax * m_ItemSize)); if(NewItemArray == NULL) return false; diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp index 63fb4301d57..6058bf28b75 100644 --- a/dep/CascLib/src/common/Common.cpp +++ b/dep/CascLib/src/common/Common.cpp @@ -207,21 +207,6 @@ LPBYTE CaptureEncodedKey(LPBYTE pbEKey, LPBYTE pbData, BYTE EKeyLength) return pbData + EKeyLength; } -LPBYTE CaptureArray_(LPBYTE pbDataPtr, LPBYTE pbDataEnd, LPBYTE * PtrArray, size_t ItemSize, size_t ItemCount) -{ - size_t ArraySize = ItemSize * ItemCount; - - // Is there enough data? - if((pbDataPtr + ArraySize) > pbDataEnd) - return NULL; - - // Give data - PtrArray[0] = pbDataPtr; - - // Return the pointer to data following after the array - return pbDataPtr + ArraySize; -} - //----------------------------------------------------------------------------- // String copying and conversion @@ -598,7 +583,7 @@ bool CascIsValidMD5(LPBYTE pbMd5) return (Int32Array[0] | Int32Array[1] | Int32Array[2] | Int32Array[3]) ? true : false; } -bool CascVerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5) +bool CascVerifyDataBlockHash(void * pvDataBlock, size_t cbDataBlock, LPBYTE expected_md5) { MD5_CTX md5_ctx; BYTE md5_digest[MD5_HASH_SIZE]; @@ -609,18 +594,27 @@ bool CascVerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expec // Calculate the MD5 of the data block MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, pvDataBlock, cbDataBlock); + MD5_Update(&md5_ctx, pvDataBlock, (unsigned long)(cbDataBlock)); MD5_Final(md5_digest, &md5_ctx); // Does the MD5's match? return (memcmp(md5_digest, expected_md5, MD5_HASH_SIZE) == 0); } -void CascCalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash) +void CascHash_MD5(const void * pvDataBlock, size_t cbDataBlock, LPBYTE md5_hash) { MD5_CTX md5_ctx; MD5_Init(&md5_ctx); - MD5_Update(&md5_ctx, pvDataBlock, cbDataBlock); + MD5_Update(&md5_ctx, pvDataBlock, (unsigned long)(cbDataBlock)); MD5_Final(md5_hash, &md5_ctx); } + +void CascHash_SHA1(const void * pvDataBlock, size_t cbDataBlock, LPBYTE sha1_hash) +{ + SHA1_CTX sha1_ctx; + + SHA1_Init(&sha1_ctx); + SHA1_Update(&sha1_ctx, pvDataBlock, (u32)(cbDataBlock)); + SHA1_Final(&sha1_ctx, sha1_hash); +} diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h index 5abc5c77b9a..c6671c277b5 100644 --- a/dep/CascLib/src/common/Common.h +++ b/dep/CascLib/src/common/Common.h @@ -59,18 +59,19 @@ typedef struct _CASC_EKEY_ENTRY // in the storage. Note that the file may be present under several file names. // Flags for CASC_CKEY_ENTRY::Flags -#define CASC_CE_FILE_IS_LOCAL 0x00000001 // The file is available locally. Keep this flag to have value of 1 -#define CASC_CE_HAS_CKEY 0x00000002 // The CKey is present in the entry -#define CASC_CE_HAS_EKEY 0x00000004 // The EKey is present, at least partial one -#define CASC_CE_HAS_EKEY_PARTIAL 0x00000008 // The EKey is only partial, padded by zeros. Always used with CASC_CE_HAS_EKEY -#define CASC_CE_IN_ENCODING 0x00000010 // Present in the ENCODING manifest -#define CASC_CE_IN_DOWNLOAD 0x00000020 // Present in the DOWNLOAD manifest -#define CASC_CE_IN_BUILD 0x00000040 // Present in the BUILD (text) manifest -#define CASC_CE_IN_ARCHIVE 0x00000080 // File is stored in an archive (for online storages) -#define CASC_CE_FOLDER_ENTRY 0x00000100 // This CKey entry is a folder -#define CASC_CE_FILE_SPAN 0x00000200 // This CKey entry is a follow-up file span -#define CASC_CE_FILE_PATCH 0x00000400 // The file is in PATCH subfolder in remote storage -#define CASC_CE_PLAIN_DATA 0x00000800 // The file data is not BLTE encoded, but in plain format +#define CASC_CE_FILE_IS_LOCAL 0x0001 // The file is available locally. Keep this flag to have value of 1 +#define CASC_CE_HAS_CKEY 0x0002 // The CKey is present in the entry +#define CASC_CE_HAS_EKEY 0x0004 // The EKey is present, at least partial one +#define CASC_CE_HAS_EKEY_PARTIAL 0x0008 // The EKey is only partial, padded by zeros. Always used with CASC_CE_HAS_EKEY +#define CASC_CE_IN_ENCODING 0x0010 // Present in the ENCODING manifest +#define CASC_CE_IN_DOWNLOAD 0x0020 // Present in the DOWNLOAD manifest +#define CASC_CE_IN_BUILD 0x0040 // Present in the BUILD (text) manifest +#define CASC_CE_IN_ARCHIVE 0x0080 // File is stored in an archive (for online storages) +#define CASC_CE_FOLDER_ENTRY 0x0100 // This CKey entry is a folder +#define CASC_CE_FILE_SPAN 0x0200 // This CKey entry is a follow-up file span +#define CASC_CE_FILE_PATCH 0x0400 // The file is in PATCH subfolder in remote storage +#define CASC_CE_PLAIN_DATA 0x0800 // The file data is not BLTE encoded, but in plain format +#define CASC_CE_OPEN_CKEY_ONCE 0x1000 // Used by CascLib test program - only opens a file with given CKey once, regardless on how many file names does it have // In-memory representation of a single entry. struct CASC_CKEY_ENTRY @@ -112,10 +113,10 @@ struct CASC_CKEY_ENTRY ULONGLONG TagBitMask; // Bitmap for the tags. 0 ig tags are not supported DWORD ContentSize; // Content size of the file DWORD EncodedSize; // Encoded size of the file - DWORD Flags; // See CASC_CE_XXX - USHORT RefCount; // This is the number of file names referencing this entry + DWORD RefCount; // This is the number of file names referencing this entry + USHORT Flags; // See CASC_CE_XXX BYTE SpanCount; // Number of spans for the file - BYTE Priority; // Download priority + BYTE Priority; // Number of spans for the file }; typedef CASC_CKEY_ENTRY *PCASC_CKEY_ENTRY; @@ -143,12 +144,9 @@ extern unsigned char IntToHexChar[]; template <typename T> T * CASC_REALLOC(T * old_ptr, size_t count) { - T * new_ptr = (T *)realloc(old_ptr, count * sizeof(T)); - - // If realloc fails, then the old buffer remains unfreed - if(new_ptr == NULL) - free(old_ptr); - return new_ptr; + // Note: If realloc fails, then the old buffer remains unfreed! + // The caller needs to handle this + return (T *)realloc(old_ptr, count * sizeof(T)); } template <typename T> @@ -310,9 +308,43 @@ LPBYTE CaptureInteger32_BE(LPBYTE pbDataPtr, LPBYTE pbDataEnd, PDWORD PtrValue); LPBYTE CaptureByteArray(LPBYTE pbDataPtr, LPBYTE pbDataEnd, size_t nLength, LPBYTE pbOutput); LPBYTE CaptureContentKey(LPBYTE pbDataPtr, LPBYTE pbDataEnd, PCONTENT_KEY * PtrCKey); LPBYTE CaptureEncodedKey(LPBYTE pbEKey, LPBYTE pbData, BYTE EKeyLength); -LPBYTE CaptureArray_(LPBYTE pbDataPtr, LPBYTE pbDataEnd, LPBYTE * PtrArray, size_t ItemSize, size_t ItemCount); -#define CaptureArray(pbDataPtr, pbDataEnd, PtrArray, type, count) CaptureArray_(pbDataPtr, pbDataEnd, PtrArray, sizeof(type), count) +template <typename STRUCTURE> +LPBYTE CaptureStructure(LPBYTE pbDataPtr, LPBYTE pbDataEnd, STRUCTURE ** lpStructure) +{ + if((pbDataPtr + sizeof(STRUCTURE)) <= pbDataEnd) + { + lpStructure[0] = (STRUCTURE *)(pbDataPtr); + return pbDataPtr + sizeof(STRUCTURE); + } + return NULL; +} + +template <typename STRUCTURE> +LPBYTE CaptureArray(LPBYTE pbDataPtr, LPBYTE pbDataEnd, STRUCTURE ** PtrArray, size_t nCount) +{ + size_t nTotalSize = nCount * sizeof(STRUCTURE); + + if((pbDataPtr + nTotalSize) <= pbDataEnd) + { + PtrArray[0] = (STRUCTURE *)(pbDataPtr); + return pbDataPtr + nTotalSize; + } + return NULL; +} + +template <typename STRUCTURE> +LPBYTE CaptureArrayAsByte(LPBYTE pbDataPtr, LPBYTE pbDataEnd, LPBYTE * PtrArray, size_t nCount) +{ + size_t nTotalSize = nCount * sizeof(STRUCTURE); + + if((pbDataPtr + nTotalSize) <= pbDataEnd) + { + PtrArray[0] = (LPBYTE)(pbDataPtr); + return pbDataPtr + nTotalSize; + } + return NULL; +} //----------------------------------------------------------------------------- // String copying and conversion @@ -571,8 +603,9 @@ bool CascCheckWildCard(const char * szString, const char * szWildCard); // Hashing functions bool CascIsValidMD5(LPBYTE pbMd5); -void CascCalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash); -bool CascVerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5); +void CascHash_MD5(const void * pvDataBlock, size_t cbDataBlock, LPBYTE md5_hash); +void CascHash_SHA1(const void * pvDataBlock, size_t cbDataBlock, LPBYTE sha1_hash); +bool CascVerifyDataBlockHash(void * pvDataBlock, size_t cbDataBlock, LPBYTE expected_md5); //----------------------------------------------------------------------------- // Argument structure versioning diff --git a/dep/CascLib/src/common/FileTree.cpp b/dep/CascLib/src/common/FileTree.cpp index 453034c057d..5c4770d8655 100644 --- a/dep/CascLib/src/common/FileTree.cpp +++ b/dep/CascLib/src/common/FileTree.cpp @@ -87,7 +87,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertNew(PCASC_CKEY_ENTRY pCKeyEntry) // Don't insert the node into any of the arrays here. // That is the caller's responsibility } - return pFileNode; } @@ -123,7 +122,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertNew() } } } - return pFileNode; } @@ -162,7 +160,6 @@ bool CASC_FILE_TREE::InsertToIdTable(PCASC_FILE_NODE pFileNode) } } } - return false; } @@ -183,7 +180,6 @@ bool CASC_FILE_TREE::SetNodePlainName(PCASC_FILE_NODE pFileNode, const char * sz pFileNode->NameLength = (USHORT)nLength; return true; } - return false; } @@ -233,7 +229,6 @@ bool CASC_FILE_TREE::RebuildNameMaps() InsertToIdTable(pFileNode); } } - return true; } @@ -344,6 +339,7 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertByName(PCASC_CKEY_ENTRY pCKeyEntry, const { // Supply the name hash pFileNode->FileNameHash = FileNameHash; + //bNewNodeInserted = true; // Set the file data id and the extra values SetExtras(pFileNode, FileDataId, LocaleFlags, ContentFlags); @@ -358,8 +354,7 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertByName(PCASC_CKEY_ENTRY pCKeyEntry, const SetNodeFileName(pFileNode, szFileName); // If we created a new node, we need to increment the reference count - assert(pCKeyEntry->RefCount != 0xFFFF); - //bNewNodeInserted = true; + assert(pCKeyEntry->RefCount < 0xFFFFFFFF); pCKeyEntry->RefCount++; FileNodes++; } @@ -392,7 +387,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertByHash(PCASC_CKEY_ENTRY pCKeyEntry, ULONGL // Insert the file node to the hash map InsertToNameMap(pFileNode); } - return pFileNode; } @@ -422,8 +416,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertById(PCASC_CKEY_ENTRY pCKeyEntry, DWORD Fi pCKeyEntry->RefCount++; } } - - // Return the new or old node return pFileNode; } @@ -443,7 +435,7 @@ PCASC_FILE_NODE CASC_FILE_TREE::PathAt(char * szBuffer, size_t cchBuffer, size_t RefFileNode = (PCASC_FILE_NODE *)FileDataIds.ItemAt(nItemIndex); if(RefFileNode != NULL) { - pFileNode = *(PCASC_FILE_NODE *)FileDataIds.ItemAt(nItemIndex); + pFileNode = RefFileNode[0]; } } else @@ -451,7 +443,7 @@ PCASC_FILE_NODE CASC_FILE_TREE::PathAt(char * szBuffer, size_t cchBuffer, size_t pFileNode = (PCASC_FILE_NODE)NodeTable.ItemAt(nItemIndex); } - // Construct the entire path + // Construct the full path PathAt(szBuffer, cchBuffer, pFileNode); return pFileNode; } @@ -522,7 +514,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::Find(const char * szFullPath, DWORD FileDataId, { GetExtras(pFileNode, &pFindData->dwFileDataId, &pFindData->dwLocaleFlags, &pFindData->dwContentFlags); } - return pFileNode; } @@ -539,7 +530,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::Find(PCASC_CKEY_ENTRY pCKeyEntry) return pFileNode; } } - return NULL; } @@ -562,7 +552,6 @@ PCASC_FILE_NODE CASC_FILE_TREE::FindById(DWORD FileDataId) pFileNode = RefElement[0]; } } - return pFileNode; } diff --git a/dep/CascLib/src/common/FileTree.h b/dep/CascLib/src/common/FileTree.h index 0e178c769bb..c74b3f73f16 100644 --- a/dep/CascLib/src/common/FileTree.h +++ b/dep/CascLib/src/common/FileTree.h @@ -19,7 +19,7 @@ #define FTREE_FLAG_USE_CONTENT_FLAGS 0x0004 // The FILE_NODE also contains content flags #define CFN_FLAG_FOLDER 0x0001 // This item is a folder -#define CFN_FLAG_MOUNT_POINT 0x0002 // This item is a mount point. +#define CFN_FLAG_MOUNT_POINT 0x0002 // This item is a mount point // Common structure for holding a single folder/file node typedef struct _CASC_FILE_NODE diff --git a/dep/CascLib/src/common/Map.h b/dep/CascLib/src/common/Map.h index 54dda5baed8..68177c466fc 100644 --- a/dep/CascLib/src/common/Map.h +++ b/dep/CascLib/src/common/Map.h @@ -15,7 +15,6 @@ // Structures #define MIN_HASH_TABLE_SIZE 0x00000100 // The smallest size of the hash table. -#define MAX_HASH_TABLE_SIZE 0x00800000 // The largest size of the hash table. Should be enough for any game. typedef int (*PFNCOMPAREFUNC)(const void * pvObjectKey, const void * pvKey, size_t nKeyLength); typedef DWORD (*PFNHASHFUNC)(void * pvKey, size_t nKeyLength); @@ -36,7 +35,7 @@ typedef enum _KEY_TYPE inline DWORD CalcHashValue_Hash(void * pvKey, size_t /* nKeyLength */) { // Get the hash directly as value - return ConvertBytesToInteger_4((LPBYTE)pvKey); + return ConvertBytesToInteger_4_LE((LPBYTE)pvKey); } // Calculates hash value from a key @@ -328,20 +327,22 @@ class CASC_MAP size_t GetNearestPowerOfTwo(size_t MaxItems) { - size_t PowerOfTwo; + size_t PowerOfTwo = MIN_HASH_TABLE_SIZE; // Round the hash table size up to the nearest power of two - for(PowerOfTwo = MIN_HASH_TABLE_SIZE; PowerOfTwo <= MAX_HASH_TABLE_SIZE; PowerOfTwo <<= 1) + while(PowerOfTwo < MaxItems) { - if(PowerOfTwo > MaxItems) + // Overflow check + if((PowerOfTwo << 1) < PowerOfTwo) { - return PowerOfTwo; + assert(false); + return 0; } - } - // If the hash table is too big, we cannot create the map - assert(false); - return 0; + // Shift the value + PowerOfTwo <<= 1; + } + return PowerOfTwo; } PFNHASHFUNC PfnCalcHashValue; diff --git a/dep/CascLib/src/common/RootHandler.cpp b/dep/CascLib/src/common/RootHandler.cpp index 227eaff6b96..3237c7987c0 100644 --- a/dep/CascLib/src/common/RootHandler.cpp +++ b/dep/CascLib/src/common/RootHandler.cpp @@ -80,7 +80,7 @@ PCASC_CKEY_ENTRY TFileTreeRoot::Search(TCascSearch * pSearch, PCASC_FIND_DATA pF //BREAKIF(pSearch->nFileIndex >= 2823765); // Retrieve the file item - pFileNode = FileTree.PathAt(pFindData->szFileName, MAX_PATH, pSearch->nFileIndex++); + pFileNode = FileTree.PathAt(pFindData->szFileName, _countof(pFindData->szFileName), pSearch->nFileIndex++); if(pFileNode != NULL) { // Ignore folders, but report mount points. These can and should be able to open and read diff --git a/dep/CascLib/src/common/RootHandler.h b/dep/CascLib/src/common/RootHandler.h index f9ea76b5f3a..a53cc4c2405 100644 --- a/dep/CascLib/src/common/RootHandler.h +++ b/dep/CascLib/src/common/RootHandler.h @@ -17,7 +17,7 @@ #define CASC_MNDX_ROOT_SIGNATURE 0x58444E4D // 'MNDX' #define CASC_TVFS_ROOT_SIGNATURE 0x53465654 // 'TVFS' #define CASC_DIABLO3_ROOT_SIGNATURE 0x8007D0C4 -#define CASC_WOW82_ROOT_SIGNATURE 0x4D465354 // 'TSFM', WoW since 8.2 +#define CASC_WOW_ROOT_SIGNATURE 0x4D465354 // 'TSFM', since WoW build 30080 (8.2.0) #define DUMP_LEVEL_ROOT_FILE 1 // Dump root file #define DUMP_LEVEL_ENCODING_FILE 2 // Dump root file + encoding file diff --git a/dep/CascLib/src/common/Sockets.cpp b/dep/CascLib/src/common/Sockets.cpp index 8eb9680d448..954466351b2 100644 --- a/dep/CascLib/src/common/Sockets.cpp +++ b/dep/CascLib/src/common/Sockets.cpp @@ -47,6 +47,7 @@ static HANDLE inline SocketToHandle(SOCKET sock) // Guarantees that there is zero terminator after the response char * CASC_SOCKET::ReadResponse(const char * request, size_t request_length, CASC_MIME_RESPONSE & MimeResponse) { + char * new_server_response = NULL; char * server_response = NULL; size_t total_received = 0; size_t buffer_length = BUFFER_INITIAL_SIZE; @@ -83,12 +84,16 @@ char * CASC_SOCKET::ReadResponse(const char * request, size_t request_length, CA // Reallocate the buffer size, if needed if(total_received == buffer_length) { - // Reallocate the buffer - if((server_response = CASC_REALLOC(server_response, buffer_length + buffer_delta + 1)) == NULL) + // Reallocate the buffer. Note that if this fails, the old buffer remains valid + if((new_server_response = CASC_REALLOC(server_response, buffer_length + buffer_delta + 1)) == NULL) { dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + CASC_FREE(server_response); break; } + + // Setup the new buffer + server_response = new_server_response; buffer_length += buffer_delta; buffer_delta = BUFFER_INITIAL_SIZE; } |