⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloadwithtiger.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	
	DWORD nTarget = 0xFFFFFFFF;
	
	if ( m_pFile == NULL )
	{
		for ( TRISTATE nState = TS_UNKNOWN ; nState < TS_TRUE ; nState++ )
		{
			for ( DWORD nBlock = 0 ; nBlock < nBlockCount ; nBlock ++ )
			{
				if ( pBlockPtr[ nBlock ] == nState )
				{
					nTarget = nBlock;
					break;
				}
			}
			
			if ( nTarget != 0xFFFFFFFF ) break;
		}
	}
	else
	{
		DWORD nRetry = 0xFFFFFFFF;
		QWORD nPrevious = 0;
		
		for ( CFileFragment* pFragment = m_pFile->GetFirstEmptyFragment() ; pFragment ; pFragment = pFragment->m_pNext )
		{
			if ( pFragment->m_nOffset - nPrevious >= nBlockSize )
			{
				DWORD nBlock = (DWORD)( ( nPrevious + nBlockSize - 1 ) / nBlockSize );
				nPrevious = nBlockSize * (QWORD)nBlock + nBlockSize;
				
				for ( ; nPrevious <= pFragment->m_nOffset ; nBlock ++, nPrevious += nBlockSize )
				{
					if ( pBlockPtr[ nBlock ] == TS_UNKNOWN )
					{
						nTarget = nBlock;
						break;
					}
					else if ( pBlockPtr[ nBlock ] == TS_FALSE && nRetry == 0xFFFFFFFF )
					{
						nRetry = nBlock;
					}
				}
				
				if ( nTarget != 0xFFFFFFFF ) break;
			}
			
			nPrevious = pFragment->m_nOffset + pFragment->m_nLength;
		}
		
		if ( m_nSize > nPrevious && nTarget == 0xFFFFFFFF )
		{
			DWORD nBlock = (DWORD)( ( nPrevious + nBlockSize - 1 ) / nBlockSize );
			nPrevious = nBlockSize * (QWORD)nBlock;
			
			for ( ; nPrevious < m_nSize ; nBlock ++, nPrevious += nBlockSize )
			{
				if ( pBlockPtr[ nBlock ] == TS_UNKNOWN )
				{
					nTarget = nBlock;
					break;
				}
				else if ( pBlockPtr[ nBlock ] == TS_FALSE && nRetry == 0xFFFFFFFF )
				{
					nRetry = nBlock;
				}
			}
		}
		
		if ( nTarget == 0xFFFFFFFF ) nTarget = nRetry;
	}
	
	if ( nTarget != 0xFFFFFFFF )
	{
		m_nVerifyHash	= nHash;
		m_nVerifyBlock	= nTarget;
		m_nVerifyOffset	= nTarget * nBlockSize;
		m_nVerifyLength	= min( nBlockSize, m_nSize - m_nVerifyOffset );
		m_tVerifyLast	= GetTickCount();
		
		if ( m_nVerifyHash == HASH_TIGERTREE )
			m_pTigerTree.BeginBlockTest();
		else if ( m_nVerifyHash == HASH_ED2K )
			m_pHashset.BeginBlockTest();
		else if ( m_nVerifyHash == HASH_TORRENT )
			m_pTorrent.BeginBlockTest();
		
		return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger validation process

void CDownloadWithTiger::ContinueValidation()
{
	ASSERT( m_nVerifyHash > HASH_NULL );
	ASSERT( m_nVerifyBlock < 0xFFFFFFFF );
	
	BOOL bDone = ( m_pFile == NULL ) || ( m_pFile->GetRemaining() == 0 );
	HANDLE hComplete = INVALID_HANDLE_VALUE;
	
	if ( m_pFile == NULL )
	{
		hComplete = CreateFile( m_sLocalName, GENERIC_READ,
			FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL, NULL );
		if ( hComplete == INVALID_HANDLE_VALUE ) return;
	}
	
	for ( int nRound = bDone ? 10 : 2 ; nRound > 0 && m_nVerifyLength > 0 ; nRound-- )
	{
		DWORD nChunk	= (DWORD)min( m_nVerifyLength, Transfers.m_nBuffer );
		LPBYTE pChunk	= Transfers.m_pBuffer;
		
		if ( m_pFile != NULL )
		{
			m_pFile->ReadRange( m_nVerifyOffset, pChunk, nChunk );
		}
		else
		{
			LONG nOffsetHigh = (LONG)( m_nVerifyOffset >> 32 );
			SetFilePointer( hComplete, (DWORD)( m_nVerifyOffset & 0xFFFFFFFF ), &nOffsetHigh, FILE_BEGIN );
			ReadFile( hComplete, pChunk, nChunk, &nChunk, NULL );
		}
		
		if ( m_nVerifyHash == HASH_TIGERTREE )
			m_pTigerTree.AddToTest( pChunk, (DWORD)nChunk );
		else if ( m_nVerifyHash == HASH_ED2K )
			m_pHashset.AddToTest( pChunk, (DWORD)nChunk );
		else if ( m_nVerifyHash == HASH_TORRENT )
			m_pTorrent.AddToTest( pChunk, (DWORD)nChunk );
		else
			ASSERT( FALSE );
		
		m_nVerifyOffset += nChunk;
		m_nVerifyLength -= nChunk;
	}
	
	if ( hComplete != INVALID_HANDLE_VALUE ) CloseHandle( hComplete );
	if ( m_nVerifyLength == 0 ) FinishValidation();
}

void CDownloadWithTiger::FinishValidation()
{
	CFileFragment* pCorrupted = NULL;
	
	if ( m_nVerifyHash == HASH_TIGERTREE )
	{
		if ( m_pTigerTree.FinishBlockTest( m_nVerifyBlock ) )
		{
			m_pTigerBlock[ m_nVerifyBlock ] = TS_TRUE;
			m_nTigerSuccess ++;
		}
		else
		{
			m_pTigerBlock[ m_nVerifyBlock ] = TS_FALSE;
			
			pCorrupted = CFileFragment::New();
			pCorrupted->m_nOffset	= m_nVerifyBlock * m_nTigerSize;
			pCorrupted->m_nLength	= min( m_nTigerSize, m_nSize - pCorrupted->m_nOffset );
		}
	}
	else if ( m_nVerifyHash == HASH_ED2K )
	{
		if ( m_pHashset.FinishBlockTest( m_nVerifyBlock ) )
		{
			m_pHashsetBlock[ m_nVerifyBlock ] = TS_TRUE;
			m_nHashsetSuccess ++;
		}
		else
		{
			m_pHashsetBlock[ m_nVerifyBlock ] = TS_FALSE;
			
			pCorrupted = CFileFragment::New();
			pCorrupted->m_nOffset	= m_nVerifyBlock * ED2K_PART_SIZE;
			pCorrupted->m_nLength	= min( ED2K_PART_SIZE, m_nSize - pCorrupted->m_nOffset );
		}
	}
	else if ( m_nVerifyHash == HASH_TORRENT )
	{
		if ( m_pTorrent.FinishBlockTest( m_nVerifyBlock ) )
		{
			m_pTorrentBlock[ m_nVerifyBlock ] = TS_TRUE;
			m_nTorrentSuccess ++;
			
			OnFinishedTorrentBlock( m_nVerifyBlock );
		}
		else
		{
			m_pTorrentBlock[ m_nVerifyBlock ] = TS_FALSE;
			
			pCorrupted = CFileFragment::New();
			pCorrupted->m_nOffset	= m_nVerifyBlock * m_nTorrentSize;
			pCorrupted->m_nLength	= min( m_nTorrentSize, m_nSize - pCorrupted->m_nOffset );
		}
	}
	
	if ( pCorrupted != NULL && m_pFile != NULL )
	{
		if ( m_pTigerBlock != NULL )
			SubtractHelper( &pCorrupted, m_pTigerBlock, m_nTigerBlock, m_nTigerSize );
		if ( m_pHashsetBlock != NULL )
			SubtractHelper( &pCorrupted, m_pHashsetBlock, m_nHashsetBlock, ED2K_PART_SIZE );
		if ( m_pTorrentBlock != NULL )
			SubtractHelper( &pCorrupted, m_pTorrentBlock, m_nTorrentBlock, m_nTorrentSize );
		
		for ( CFileFragment* pRange = pCorrupted ; pRange ; pRange = pRange->m_pNext )
		{
			m_pFile->InvalidateRange( pRange->m_nOffset, pRange->m_nLength );
			RemoveOverlappingSources( pRange->m_nOffset, pRange->m_nLength );
		}
		
		pCorrupted->DeleteChain();
	}
	
	m_nVerifyHash	= HASH_NULL;
	m_nVerifyBlock	= 0xFFFFFFFF;
	m_nVerifyCookie++;
	
	SetModified();
}

void CDownloadWithTiger::SubtractHelper(CFileFragment** ppCorrupted, BYTE* pBlock, QWORD nBlock, QWORD nSize)
{
	QWORD nOffset = 0;
	
	while ( nBlock-- && *ppCorrupted )
	{
		if ( *pBlock++ == TS_TRUE )
		{
			CFileFragment::Subtract( ppCorrupted, nOffset, nSize );
		}
		
		nOffset += nSize;
	}
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger available ranges override

CString CDownloadWithTiger::GetAvailableRanges() const
{
	CString strRanges, strRange;
	QWORD nOffset, nLength;
	BOOL bSuccess;
	
	for ( nOffset = 0 ; GetNextVerifyRange( nOffset, nLength, bSuccess ) ; )
	{
		if ( bSuccess )
		{
			if ( strRanges.IsEmpty() )
				strRanges = _T("bytes ");
			else
				strRanges += ',';
			
			strRange.Format( _T("%I64i-%I64i"), nOffset, nOffset + nLength - 1 );
			strRanges += strRange;
		}
		
		nOffset += nLength;
	}
	
	if ( strRanges.IsEmpty() ) strRanges = CDownloadWithTorrent::GetAvailableRanges();
	
	return strRanges;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger clear data

void CDownloadWithTiger::ResetVerification()
{
	if ( m_nVerifyHash == HASH_TIGERTREE )
	{
		m_pTigerTree.FinishBlockTest( m_nVerifyBlock );
	}
	else if ( m_nVerifyHash == HASH_ED2K )
	{
		m_pHashset.FinishBlockTest( m_nVerifyBlock );
	}
	else if ( m_nVerifyHash == HASH_TORRENT )
	{
		m_pTorrent.FinishBlockTest( m_nVerifyBlock );
	}
	
	if ( m_pTigerBlock != NULL ) ZeroMemory( m_pTigerBlock, m_nTigerBlock );
	if ( m_pHashsetBlock != NULL ) ZeroMemory( m_pHashsetBlock, m_nHashsetBlock );
	if ( m_pTorrentBlock != NULL ) ZeroMemory( m_pTorrentBlock, m_nTorrentBlock );
	
	m_nTigerSuccess		= 0;
	m_nHashsetSuccess	= 0;
	m_nTorrentSuccess	= 0;
	
	m_nVerifyHash		= HASH_NULL;
	m_nVerifyBlock		= 0xFFFFFFFF;
	
	m_nVerifyCookie++;
	SetModified();
}

void CDownloadWithTiger::ClearVerification()
{
	ResetVerification();
	
	if ( m_pTigerBlock != NULL ) delete [] m_pTigerBlock;
	if ( m_pHashsetBlock != NULL ) delete [] m_pHashsetBlock;
	
	m_pTigerBlock		= NULL;
	m_nTigerBlock		= 0;
	m_pHashsetBlock		= NULL;
	m_nHashsetBlock		= 0;
	
	m_pTigerTree.Clear();
	m_pHashset.Clear();
	
	m_nVerifyCookie++;
	SetModified();
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithTiger serialize

void CDownloadWithTiger::Serialize(CArchive& ar, int nVersion)
{
	CDownloadWithTorrent::Serialize( ar, nVersion );
	
	m_pTigerTree.Serialize( ar );
	
	if ( m_pTigerTree.IsAvailable() )
	{
		if ( ar.IsStoring() )
		{
			ar << m_nTigerBlock;
			ar << m_nTigerSize;
			ar << m_nTigerSuccess;
			ar.Write( m_pTigerBlock, sizeof(BYTE) * m_nTigerBlock );
		}
		else
		{
			m_pTigerTree.SetupParameters( m_nSize );
			
			ar >> m_nTigerBlock;
			ar >> m_nTigerSize;
			ar >> m_nTigerSuccess;
			
			m_pTigerBlock = new BYTE[ m_nTigerBlock ];
			ar.Read( m_pTigerBlock, sizeof(BYTE) * m_nTigerBlock );
		}
	}
	
	if ( nVersion >= 19 )
	{
		m_pHashset.Serialize( ar );
		
		if ( m_pHashset.IsAvailable() )
		{
			if ( ar.IsStoring() )
			{
				ar << m_nHashsetBlock;
				ar << m_nHashsetSuccess;
				ar.Write( m_pHashsetBlock, sizeof(BYTE) * m_nHashsetBlock );
			}
			else
			{
				ar >> m_nHashsetBlock;
				ar >> m_nHashsetSuccess;
				
				m_pHashsetBlock = new BYTE[ m_nHashsetBlock ];
				ar.Read( m_pHashsetBlock, sizeof(BYTE) * m_nHashsetBlock );
			}
		}
	}
	
	if ( nVersion < 30 && m_bBTH )
	{
		ClearVerification();
		m_bSHA1 = m_bTiger = m_bED2K = FALSE;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -