static int LoadFileFrames(TCascFile * hf) { PBLTE_FRAME pFileFrames; PBLTE_FRAME pFileFrame; ULONGLONG ArchiveFileOffset; DWORD FrameOffset = 0; DWORD FileSize = 0; int nError = ERROR_SUCCESS; assert(hf != NULL); assert(hf->pStream != NULL); assert(hf->pFrames != NULL); // Allocate frame array pFileFrames = pFileFrame = CASC_ALLOC(BLTE_FRAME, hf->FrameCount); if(pFileFrames != NULL) { // Load the frame array ArchiveFileOffset = hf->FramesOffset; if(FileStream_Read(hf->pStream, &ArchiveFileOffset, pFileFrames, hf->FrameCount * sizeof(BLTE_FRAME))) { // Move the raw archive offset ArchiveFileOffset += (hf->FrameCount * sizeof(BLTE_FRAME)); // Copy the frames to the file structure for(DWORD i = 0; i < hf->FrameCount; i++, pFileFrame++) { hf->pFrames[i].FrameArchiveOffset = (DWORD)ArchiveFileOffset; hf->pFrames[i].FrameFileOffset = FrameOffset; hf->pFrames[i].CompressedSize = ConvertBytesToInteger_4(pFileFrame->CompressedSize); hf->pFrames[i].FrameSize = ConvertBytesToInteger_4(pFileFrame->FrameSize); memcpy(hf->pFrames[i].md5, pFileFrame->md5, MD5_HASH_SIZE); ArchiveFileOffset += hf->pFrames[i].CompressedSize; FrameOffset += hf->pFrames[i].FrameSize; FileSize += hf->pFrames[i].FrameSize; } } else nError = GetLastError(); // Note: on ENCODING file, this value is almost always bigger // then the real size of ENCODING. We handle this problem // by calculating size of the ENCODIG file from its header. hf->FileSize = FileSize; #ifdef CASCLIB_TEST hf->FileSize_FrameSum = FileSize; #endif // Free the array CASC_FREE(pFileFrames); } else nError = ERROR_NOT_ENOUGH_MEMORY; return nError; }
static LPBYTE WowHandler_GetKey(TRootHandler_WoW6 * pRootHandler, const char * szFileName) { PCASC_FILE_ENTRY pFileEntry; DWORD FileDataId; BYTE FileDataIdLE[4]; // Open by FileDataId. The file name must be as following: // File########.xxx, where '#' are hexa-decimal numbers (case insensitive). // Extension is ignored in that case if(IsFileDataIdName(szFileName)) { ConvertStringToBinary(szFileName + 4, 8, FileDataIdLE); FileDataId = ConvertBytesToInteger_4(FileDataIdLE); pFileEntry = FindRootEntry(pRootHandler->FileTable, FileDataId); } else { // Find by the file name hash pFileEntry = FindRootEntry(pRootHandler->pRootMap, szFileName, NULL); } return (pFileEntry != NULL) ? pFileEntry->EncodingKey.Value : NULL; }
static int EnsureHeaderAreaIsLoaded(TCascFile * hf) { TCascStorage * hs = hf->hs; ULONGLONG FileOffset = hf->HeaderOffset; LPBYTE pbHeaderArea; DWORD FileSignature; DWORD FileSize; BYTE HeaderArea[MAX_HEADER_AREA_SIZE]; int nError; // We need the data file to be open nError = EnsureDataStreamIsOpen(hf); if(nError != ERROR_SUCCESS) return nError; // Make sure that we already know the shift // to the begin of file data. // Note that older builds of Heroes of the Storm have entries pointing // to the beginning of the header area. // Newer versions of HOTS have encoding entries pointing directly to // the BLTE header if(hs->dwFileBeginDelta == 0xFFFFFFFF) { FileSignature = 0; FileOffset = hf->HeaderOffset; if(!FileStream_Read(hf->pStream, &FileOffset, &FileSignature, sizeof(DWORD))) return ERROR_FILE_CORRUPT; hs->dwFileBeginDelta = (FileSignature == BLTE_HEADER_SIGNATURE) ? BLTE_HEADER_DELTA : 0; } // If the file size is not loaded yet, do it if(hf->FrameCount == 0) { // Load the part before BLTE header + header itself FileOffset = hf->HeaderOffset - hs->dwFileBeginDelta; if(!FileStream_Read(hf->pStream, &FileOffset, HeaderArea, sizeof(HeaderArea))) return ERROR_FILE_CORRUPT; // Copy the MD5 hash of the frame array memcpy(hf->FrameArrayHash, HeaderArea, MD5_HASH_SIZE); pbHeaderArea = HeaderArea + MD5_HASH_SIZE; // Copy the file size FileSize = ConvertBytesToInteger_4_LE(pbHeaderArea); pbHeaderArea += 0x0E; // Verify the BLTE signature if(ConvertBytesToInteger_4_LE(pbHeaderArea) != BLTE_HEADER_SIGNATURE) return ERROR_BAD_FORMAT; pbHeaderArea += sizeof(DWORD); // Load the size of the frame headers hf->HeaderSize = ConvertBytesToInteger_4(pbHeaderArea); if(hf->HeaderSize & 0x80000000) return ERROR_BAD_FORMAT; pbHeaderArea += sizeof(DWORD); // Read the header size assert(hs->dwFileBeginDelta <= BLTE_HEADER_DELTA); hf->HeaderOffset += (BLTE_HEADER_DELTA - hs->dwFileBeginDelta); hf->FrameCount = 1; // Retrieve the frame count, if different from 1 if(hf->HeaderSize != 0) { // The next byte must be 0x0F if(pbHeaderArea[0] != 0x0F) return ERROR_BAD_FORMAT; pbHeaderArea++; // Next three bytes form number of frames hf->FrameCount = ConvertBytesToInteger_3(pbHeaderArea); } #ifdef CASCLIB_TEST hf->FileSize_HdrArea = FileSize; #endif } return ERROR_SUCCESS; }