aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/CascCommon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/CascLib/src/CascCommon.cpp')
-rw-r--r--dep/CascLib/src/CascCommon.cpp168
1 files changed, 111 insertions, 57 deletions
diff --git a/dep/CascLib/src/CascCommon.cpp b/dep/CascLib/src/CascCommon.cpp
index 34c3df66b5c..f5e346ec14c 100644
--- a/dep/CascLib/src/CascCommon.cpp
+++ b/dep/CascLib/src/CascCommon.cpp
@@ -13,78 +13,132 @@
#include "CascCommon.h"
//-----------------------------------------------------------------------------
-// Conversion of big-endian to integer
+// Functions
-// Read the 24-bit big-endian offset into ULONGLONG
-DWORD ConvertBytesToInteger_3(LPBYTE ValueAsBytes)
+LPBYTE LoadInternalFileToMemory(TCascStorage * hs, PCASC_CKEY_ENTRY pCKeyEntry, DWORD * pcbFileData)
{
- DWORD Value = 0;
-
- Value = (Value << 0x08) | ValueAsBytes[0];
- Value = (Value << 0x08) | ValueAsBytes[1];
- Value = (Value << 0x08) | ValueAsBytes[2];
-
- return Value;
-}
-
-// Read the 32-bit big-endian offset into ULONGLONG
-DWORD ConvertBytesToInteger_4(LPBYTE ValueAsBytes)
-{
- DWORD Value = 0;
-
- Value = (Value << 0x08) | ValueAsBytes[0];
- Value = (Value << 0x08) | ValueAsBytes[1];
- Value = (Value << 0x08) | ValueAsBytes[2];
- Value = (Value << 0x08) | ValueAsBytes[3];
-
- return Value;
-}
+ LPBYTE pbFileData = NULL;
+ HANDLE hFile = NULL;
+ DWORD cbFileData = pcbFileData[0];
+ DWORD dwBytesRead = 0;
+ int nError = ERROR_SUCCESS;
+
+ // Open the file either by CKey or by EKey
+ if(OpenFileByCKeyEntry(hs, pCKeyEntry, CASC_STRICT_DATA_CHECK, &hFile))
+ {
+ // Retrieve the size of the file. Note that the caller might specify
+ // the real size of the file, in case the file size is not retrievable
+ // or if the size is wrong. Example: ENCODING file has size specified in BUILD
+ if(cbFileData == 0 || cbFileData == CASC_INVALID_SIZE)
+ {
+ cbFileData = CascGetFileSize(hFile, NULL);
+ if(cbFileData == 0 || cbFileData == CASC_INVALID_SIZE)
+ nError = ERROR_FILE_CORRUPT;
+ }
+
+ // Retrieve the size of the ENCODING file
+ if(nError == ERROR_SUCCESS)
+ {
+ // Allocate space for the ENCODING file
+ pbFileData = CASC_ALLOC(BYTE, cbFileData);
+ if(pbFileData != NULL)
+ {
+ // Read the entire file to memory
+ CascReadFile(hFile, pbFileData, cbFileData, &dwBytesRead);
+ if(dwBytesRead != cbFileData)
+ {
+ nError = ERROR_FILE_CORRUPT;
+ }
+ }
+ else
+ {
+ nError = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ // Close the file
+ CascCloseFile(hFile);
+ }
+ else
+ {
+ nError = GetLastError();
+ }
-DWORD ConvertBytesToInteger_4_LE(LPBYTE ValueAsBytes)
-{
- DWORD Value = 0;
+ // Handle errors
+ if(nError != ERROR_SUCCESS)
+ {
+ // Free the file data
+ CASC_FREE(pbFileData);
+ cbFileData = 0;
- Value = (Value << 0x08) | ValueAsBytes[3];
- Value = (Value << 0x08) | ValueAsBytes[2];
- Value = (Value << 0x08) | ValueAsBytes[1];
- Value = (Value << 0x08) | ValueAsBytes[0];
+ // Set the last error
+ SetLastError(nError);
+ }
- return Value;
+ // Give the loaded file length
+ if(pcbFileData != NULL)
+ *pcbFileData = cbFileData;
+ return pbFileData;
}
-// Read the 40-bit big-endian offset into ULONGLONG
-ULONGLONG ConvertBytesToInteger_5(LPBYTE ValueAsBytes)
+LPBYTE LoadFileToMemory(const TCHAR * szFileName, DWORD * pcbFileData)
{
- ULONGLONG Value = 0;
-
- Value = (Value << 0x08) | ValueAsBytes[0];
- Value = (Value << 0x08) | ValueAsBytes[1];
- Value = (Value << 0x08) | ValueAsBytes[2];
- Value = (Value << 0x08) | ValueAsBytes[3];
- Value = (Value << 0x08) | ValueAsBytes[4];
-
- return Value;
-}
+ TFileStream * pStream;
+ ULONGLONG FileSize = 0;
+ LPBYTE pbFileData = NULL;
+ DWORD cbFileData = 0;
+
+ // Open the stream for read-only access and read the file
+ // Note that this fails when the game is running (sharing violation).
+ pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
+ if(pStream != NULL)
+ {
+ // Retrieve the file size
+ FileStream_GetSize(pStream, &FileSize);
+ cbFileData = (DWORD)FileSize;
+
+ // Do not load zero files or too larget files
+ if(0 < FileSize && FileSize <= 0x2000000)
+ {
+ // Allocate file data buffer. Make it 1 byte longer
+ // so string functions can put '\0' there
+ pbFileData = CASC_ALLOC(BYTE, cbFileData + 1);
+ if(pbFileData != NULL)
+ {
+ if(!FileStream_Read(pStream, NULL, pbFileData, cbFileData))
+ {
+ CASC_FREE(pbFileData);
+ cbFileData = 0;
+ }
+ }
+ else
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ cbFileData = 0;
+ }
+ }
+ else
+ {
+ SetLastError(ERROR_BAD_FORMAT);
+ cbFileData = 0;
+ assert(false);
+ }
+
+ // Close the file stream
+ FileStream_Close(pStream);
+ }
-void ConvertIntegerToBytes_4(DWORD Value, LPBYTE ValueAsBytes)
-{
- ValueAsBytes[0] = (Value >> 0x18) & 0xFF;
- ValueAsBytes[1] = (Value >> 0x10) & 0xFF;
- ValueAsBytes[2] = (Value >> 0x08) & 0xFF;
- ValueAsBytes[3] = (Value >> 0x00) & 0xFF;
+ // Give out values
+ if(pcbFileData != NULL)
+ pcbFileData[0] = cbFileData;
+ return pbFileData;
}
-//-----------------------------------------------------------------------------
-// Common fre routine of a CASC blob
-
void FreeCascBlob(PQUERY_KEY pBlob)
{
if(pBlob != NULL)
{
- if(pBlob->pbData != NULL)
- CASC_FREE(pBlob->pbData);
-
- pBlob->pbData = NULL;
+ CASC_FREE(pBlob->pbData);
pBlob->cbData = 0;
}
}