diff options
Diffstat (limited to 'dep/CascLib/src/CascCommon.cpp')
-rw-r--r-- | dep/CascLib/src/CascCommon.cpp | 168 |
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; } } |