hlBool CVBSPFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const { if(pFile->GetData()) { const ZIPFileHeader *pDirectoryItem = static_cast<const ZIPFileHeader *>(pFile->GetData()); if(pDirectoryItem->uiCompressionMethod != 0 || pDirectoryItem->uiDiskNumberStart != this->pEndOfCentralDirectoryRecord->uiNumberOfThisDisk) { eValidation = HL_VALIDATES_ASSUMED_OK; return hlTrue; } hlULong uiChecksum = 0; Streams::IStream *pStream = 0; if(this->CreateStreamInternal(pFile, pStream)) { if(pStream->Open(HL_MODE_READ)) { hlULongLong uiTotalBytes = 0, uiFileBytes = pStream->GetStreamSize(); hlUInt uiBufferSize; hlByte lpBuffer[HL_VBSP_ZIP_CHECKSUM_LENGTH]; hlBool bCancel = hlFalse; hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel); while((uiBufferSize = pStream->Read(lpBuffer, sizeof(lpBuffer))) != 0) { if(bCancel) { eValidation = HL_VALIDATES_CANCELED; break; } uiChecksum = CRC32(lpBuffer, uiBufferSize, uiChecksum); uiTotalBytes += static_cast<hlULongLong>(uiBufferSize); hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel); } pStream->Close(); } this->ReleaseStreamInternal(*pStream); delete pStream; } if(eValidation == HL_VALIDATES_ASSUMED_OK) { eValidation = (hlULong)pDirectoryItem->uiCRC32 == uiChecksum ? HL_VALIDATES_OK : HL_VALIDATES_CORRUPT; } } else { eValidation = HL_VALIDATES_ASSUMED_OK; } return hlTrue; }
hlVoid CSGAFile::CSGADirectory<TSGADirectoryHeader, TSGASection, TSGAFolder, TSGAFile, TSGAFileHeader>::ReleaseStreamInternal(Streams::IStream &Stream) const { if(Stream.GetType() == HL_STREAM_MEMORY) { delete []static_cast<const hlByte *>(static_cast<Streams::CMemoryStream &>(Stream).GetBuffer()); } }
hlVoid CVBSPFile::ReleaseStreamInternal(Streams::IStream &Stream) const { if(Stream.GetType() == HL_STREAM_MEMORY) { delete [](hlByte *)static_cast<Streams::CMemoryStream &>(Stream).GetBuffer(); } }
hlVoid CPackage::Close() { if(this->pStreams != 0) { for(CStreamList::iterator i = this->pStreams->begin(); i != this->pStreams->end(); ++i) { Streams::IStream *pStream = *i; pStream->Close(); this->ReleaseStreamInternal(*pStream); delete pStream; } delete this->pStreams; this->pStreams = 0; } if(this->pMapping != 0) { this->UnmapDataStructures(); this->pMapping->Close(); } if(this->pRoot != 0) { this->ReleaseRoot(); delete this->pRoot; this->pRoot = 0; } if(this->bDeleteMapping) { delete this->pMapping; this->bDeleteMapping = hlFalse; } this->pMapping = 0; if(this->bDeleteStream) { delete this->pStream; this->bDeleteStream = hlFalse; } this->pStream = 0; }
hlVoid CVPKFile::ReleaseStreamInternal(Streams::IStream &Stream) const { if(Stream.GetType() == HL_STREAM_MEMORY) { hlByte *lpBuffer = (hlByte *)static_cast<Streams::CMemoryStream &>(Stream).GetBuffer(); const hlByte *lpView = (const hlByte *)this->pView->GetView(); if(lpBuffer < lpView || lpBuffer >= lpView + this->pView->GetLength()) { delete []lpBuffer; } } }
hlBool CVPKFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const { hlBool bExtractable = hlFalse; if(GetFileExtractableInternal(pFile, bExtractable)) { if(bExtractable) { Streams::IStream *pStream = 0; if(this->CreateStreamInternal(pFile, pStream)) { if(pStream->Open(HL_MODE_READ)) { hlULong uiChecksum = 0; eValidation = HL_VALIDATES_OK; hlULongLong uiTotalBytes = 0, uiFileBytes = pStream->GetStreamSize(); hlUInt uiBufferSize; hlByte lpBuffer[HL_VPK_CHECKSUM_LENGTH]; hlBool bCancel = hlFalse; hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel); while((uiBufferSize = pStream->Read(lpBuffer, HL_VPK_CHECKSUM_LENGTH)) != 0) { if(bCancel) { // User canceled. eValidation = HL_VALIDATES_CANCELED; break; } uiChecksum = CRC32(lpBuffer, uiBufferSize, uiChecksum); uiTotalBytes += static_cast<hlULongLong>(uiBufferSize); hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel); } if(!bCancel) { const VPKDirectoryItem *pDirectoryItem = static_cast<const VPKDirectoryItem *>(pFile->GetData()); if(pDirectoryItem->pDirectoryEntry->uiCRC != uiChecksum) { eValidation = HL_VALIDATES_CORRUPT; } } pStream->Close(); } else { eValidation = HL_VALIDATES_ERROR; } this->ReleaseStreamInternal(*pStream); delete pStream; } else { eValidation = HL_VALIDATES_ERROR; } } else { eValidation = HL_VALIDATES_INCOMPLETE; } } else { eValidation = HL_VALIDATES_ERROR; } return hlTrue; }
hlBool CDirectoryFile::Extract(const hlChar *lpPath) const { hlExtractItemStart(this); hlChar *lpName = new hlChar[strlen(this->GetName()) + 1]; strcpy(lpName, this->GetName()); RemoveIllegalCharacters(lpName); hlChar *lpFileName; if(lpPath == 0 || *lpPath == '\0') { lpFileName = new hlChar[strlen(lpName) + 1]; strcpy(lpFileName, lpName); } else { lpFileName = new hlChar[strlen(lpPath) + 1 + strlen(lpName) + 1]; strcpy(lpFileName, lpPath); strcat(lpFileName, PATH_SEPARATOR_STRING); strcat(lpFileName, lpName); } FixupIllegalCharacters(lpFileName); hlBool bResult; if(!bOverwriteFiles && GetFileExists(lpFileName)) { bResult = hlTrue; } else { bResult = hlFalse; Streams::IStream *pInput = 0; if(this->GetPackage()->CreateStream(this, pInput)) { if(pInput->Open(HL_MODE_READ)) { Streams::CFileStream Output = Streams::CFileStream(lpFileName); if(Output.Open(HL_MODE_WRITE | HL_MODE_CREATE)) { hlUInt uiTotalBytes = 0, uiFileBytes = this->GetSize(); hlByte lpBuffer[HL_DEFAULT_COPY_BUFFER_SIZE]; hlBool bCancel = hlFalse; hlExtractFileProgress(this, uiTotalBytes, uiFileBytes, &bCancel); while(hlTrue) { if(bCancel) { LastError.SetErrorMessage("Canceled by user."); } hlUInt uiBytes = pInput->Read(lpBuffer, sizeof(lpBuffer)); if(uiBytes == 0) { bResult = uiTotalBytes == pInput->GetStreamSize(); break; } if(Output.Write(lpBuffer, uiBytes) != uiBytes) { break; } uiTotalBytes += uiBytes; hlExtractFileProgress(this, uiTotalBytes, uiFileBytes, &bCancel); } Output.Close(); } pInput->Close(); } this->GetPackage()->ReleaseStream(pInput); } } delete []lpFileName; delete []lpName; hlExtractItemEnd(this, bResult); return bResult; }
hlBool CGCFFile::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const { // Do we have enough data to validate? { hlUInt uiSize = 0; // Get the first data block. hlUInt uiBlockEntryIndex = this->lpDirectoryMapEntries[pFile->GetID()].uiFirstBlockIndex; // Loop through each data block. while(uiBlockEntryIndex != this->pDataBlockHeader->uiBlockCount) { uiSize += this->lpBlockEntries[uiBlockEntryIndex].uiFileDataSize; // Get the next data block. uiBlockEntryIndex = this->lpBlockEntries[uiBlockEntryIndex].uiNextBlockEntryIndex; } if(uiSize != this->lpDirectoryEntries[pFile->GetID()].uiItemSize) { // File is incomplete. eValidation = HL_VALIDATES_INCOMPLETE; return hlTrue; } } if((this->lpDirectoryEntries[pFile->GetID()].uiDirectoryFlags & HL_GCF_FLAG_ENCRYPTED) != 0) { // No way of checking, assume it's ok. eValidation = HL_VALIDATES_ASSUMED_OK; return hlTrue; } // File has no checksum. if(this->lpDirectoryEntries[pFile->GetID()].uiChecksumIndex == 0xffffffff) { eValidation = HL_VALIDATES_ASSUMED_OK; return hlTrue; } Streams::IStream *pStream = 0; if(this->CreateStreamInternal(pFile, pStream)) { if(pStream->Open(HL_MODE_READ)) { eValidation = HL_VALIDATES_OK; hlULongLong uiTotalBytes = 0, uiFileBytes = pStream->GetStreamSize(); hlUInt uiBufferSize; hlByte lpBuffer[HL_GCF_CHECKSUM_LENGTH]; const GCFChecksumMapEntry *pChecksumMapEntry = this->lpChecksumMapEntries + this->lpDirectoryEntries[pFile->GetID()].uiChecksumIndex; hlBool bCancel = hlFalse; hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel); hlUInt i = 0; while((uiBufferSize = pStream->Read(lpBuffer, HL_GCF_CHECKSUM_LENGTH)) != 0) { if(bCancel) { // User canceled. eValidation = HL_VALIDATES_CANCELED; break; } if(i >= pChecksumMapEntry->uiChecksumCount) { // Something bad happened. eValidation = HL_VALIDATES_ERROR; break; } hlULong uiChecksum = Adler32(lpBuffer, uiBufferSize) ^ CRC32(lpBuffer, uiBufferSize); if(uiChecksum != this->lpChecksumEntries[pChecksumMapEntry->uiFirstChecksumIndex + i].uiChecksum) { eValidation = HL_VALIDATES_CORRUPT; break; } uiTotalBytes += static_cast<hlULongLong>(uiBufferSize); hlValidateFileProgress(const_cast<CDirectoryFile *>(pFile), uiTotalBytes, uiFileBytes, &bCancel); i++; } pStream->Close(); } else { eValidation = HL_VALIDATES_ERROR; } this->ReleaseStreamInternal(*pStream); delete pStream; } else { eValidation = HL_VALIDATES_ERROR; } return hlTrue; }