aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-09-05 00:10:35 +0200
committerShauren <shauren.trinity@gmail.com>2023-09-05 00:10:35 +0200
commitd57b58849bda868f2463d38cc636f01af919316c (patch)
tree5beef62c041526d9468683e4388b6341f1530cc1 /dep/CascLib/src/common
parentba224f70ad81fa0e5d1f0c4daf197e143317cdaa (diff)
Dep/CascLib: Update to ladislav-zezula/CascLib@5c60050770767f2e606f6fec0c35beb8b9b00c60
Diffstat (limited to 'dep/CascLib/src/common')
-rw-r--r--dep/CascLib/src/common/Array.h2
-rw-r--r--dep/CascLib/src/common/Common.cpp32
-rw-r--r--dep/CascLib/src/common/Common.h83
-rw-r--r--dep/CascLib/src/common/FileTree.cpp19
-rw-r--r--dep/CascLib/src/common/FileTree.h2
-rw-r--r--dep/CascLib/src/common/Map.h21
-rw-r--r--dep/CascLib/src/common/RootHandler.cpp2
-rw-r--r--dep/CascLib/src/common/RootHandler.h2
-rw-r--r--dep/CascLib/src/common/Sockets.cpp9
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;
}