BOOL CDownloadTransferBT::OnPiece(CBTPacket* pPacket) { ASSUME_LOCK( Transfers.m_pSection ); ASSERT( m_pClient != NULL ); if ( pPacket->GetRemaining() < 8 ) return TRUE; if ( m_nState != dtsRequesting && m_nState != dtsDownloading ) return TRUE; SetState( dtsDownloading ); DWORD nBlock = pPacket->ReadLongBE(); QWORD nOffset = pPacket->ReadLongBE(); QWORD nLength = pPacket->GetRemaining(); nOffset += (QWORD)nBlock * m_pDownload->m_pTorrent.m_nBlockSize; m_nDownloaded += nLength; m_pDownload->m_nTorrentDownloaded += nLength; m_pDownload->m_pTorrent.m_nTotalDownload += nLength; m_pSource->AddFragment( nOffset, nLength ); m_pSource->SetValid(); m_oRequested.erase( Fragments::Fragment( nOffset, nOffset + nLength ) ); BOOL bSuccess = m_pDownload->SubmitData( nOffset, pPacket->m_pBuffer + pPacket->m_nPosition, nLength ); if ( ! bSuccess ) TRACE( _T("[BT] Failed to submit data %I64u-%I64u to \"%s\".\n"), nOffset, nOffset + nLength, m_pDownload->m_sPath ); // TODO: SendRequests and ShowInterest could be combined.. SendRequests // is probably going to tell us if we are interested or not ShowInterest(); return SendFragmentRequests(); }
BOOL CDownloadTransferED2K::OnSendingPart64(CEDPacket* pPacket) { //if ( m_nState != dtsDownloading ) return TRUE; if ( pPacket->GetRemaining() <= Hashes::Ed2kHash::byteCount + 16 ) { theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType ); Close( TRI_FALSE ); return FALSE; } Hashes::Ed2kHash oED2K; pPacket->Read( oED2K ); if ( oED2K != m_pDownload->m_oED2K ) { theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_HASH, (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() ); // Close( TRI_FALSE ); // return FALSE; return TRUE; } QWORD nOffset = pPacket->ReadLongLE(); nOffset = ( (QWORD)pPacket->ReadLongLE() << 32 ) | nOffset; QWORD nLength = pPacket->ReadLongLE(); nLength = ( (QWORD)pPacket->ReadLongLE() << 32 ) | nLength; if ( nLength <= nOffset ) { if ( nLength == nOffset ) return TRUE; theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType ); Close( TRI_FALSE ); return FALSE; } nLength -= nOffset; if ( nLength > (QWORD)pPacket->GetRemaining() ) { theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType ); Close( TRI_FALSE ); return FALSE; } /*BOOL bUseful =*/ m_pDownload->SubmitData( nOffset, pPacket->m_pBuffer + pPacket->m_nPosition, nLength ); m_oRequested.erase( Fragments::Fragment( nOffset, nOffset + nLength ) ); m_pSource->AddFragment( nOffset, nLength, ( nOffset % ED2K_PART_SIZE ) ? TRUE : FALSE ); m_nDownloaded += nLength; m_pSource->SetValid(); return SendFragmentRequests(); }
BOOL CDownloadTransferED2K::OnStartUpload(CEDPacket* /*pPacket*/) { SetState( dtsDownloading ); m_pClient->m_mInput.tLast = GetTickCount(); ClearRequests(); return SendFragmentRequests(); }
BOOL CDownloadTransferBT::OnUnchoked(CBTPacket* /*pPacket*/) { ASSUME_LOCK( Transfers.m_pSection ); m_bChoked = FALSE; SetState( dtsTorrent ); m_oRequested.clear(); theApp.Message( MSG_DEBUG, _T("Download from %s was Unchoked."), (LPCTSTR)m_sAddress ); return SendFragmentRequests(); }
BOOL CDownloadTransferED2K::OnCompressedPart(CEDPacket* pPacket) { if ( pPacket->GetRemaining() <= Hashes::Ed2kHash::byteCount + 8 ) { theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType ); Close( TRI_FALSE ); return FALSE; } Hashes::Ed2kHash oED2K; pPacket->Read( oED2K ); if ( validAndUnequal( oED2K, m_pDownload->m_oED2K ) ) { theApp.Message( MSG_ERROR, IDS_DOWNLOAD_WRONG_HASH, (LPCTSTR)m_sAddress, (LPCTSTR)m_pDownload->GetDisplayName() ); // Close( TRI_FALSE ); // return FALSE; return TRUE; } QWORD nBaseOffset = pPacket->ReadLongLE(); QWORD nBaseLength = pPacket->ReadLongLE(); z_streamp pStream = (z_streamp)m_pInflatePtr; if ( m_pInflatePtr == NULL || m_nInflateOffset != nBaseOffset || m_nInflateLength != nBaseLength ) { if ( pStream != NULL ) { inflateEnd( pStream ); delete pStream; } m_nInflateOffset = nBaseOffset; m_nInflateLength = nBaseLength; m_nInflateRead = 0; m_nInflateWritten = 0; m_pInflateBuffer->Clear(); m_pInflatePtr = new z_stream; pStream = (z_streamp)m_pInflatePtr; ZeroMemory( pStream, sizeof( z_stream ) ); if ( inflateInit( pStream ) != Z_OK ) { delete pStream; m_pInflatePtr = NULL; theApp.Message( MSG_ERROR, IDS_DOWNLOAD_INFLATE_ERROR, (LPCTSTR)m_pDownload->GetDisplayName() ); Close( TRI_FALSE ); return FALSE; } } m_pInflateBuffer->Add( pPacket->m_pBuffer + pPacket->m_nPosition, pPacket->GetRemaining() ); auto_array< BYTE > pBuffer( new BYTE[ BUFFER_SIZE ] ); if ( m_pInflateBuffer->m_nLength > 0 && m_nInflateRead < m_nInflateLength ) { pStream->next_in = m_pInflateBuffer->m_pBuffer; pStream->avail_in = m_pInflateBuffer->m_nLength; do { pStream->next_out = pBuffer.get(); pStream->avail_out = BUFFER_SIZE; inflate( pStream, Z_SYNC_FLUSH ); if ( pStream->avail_out < BUFFER_SIZE ) { QWORD nOffset = m_nInflateOffset + m_nInflateWritten; QWORD nLength = BUFFER_SIZE - pStream->avail_out; m_pDownload->SubmitData( nOffset, pBuffer.get(), nLength ); m_oRequested.erase( Fragments::Fragment( nOffset, nOffset + nLength ) ); m_pSource->AddFragment( nOffset, nLength, ( nOffset % ED2K_PART_SIZE ) ? TRUE : FALSE ); m_nDownloaded += nLength; m_nInflateWritten += nLength; } } while ( pStream->avail_out == 0 ); if ( pStream->avail_in < m_pInflateBuffer->m_nLength ) { m_nInflateRead += ( m_pInflateBuffer->m_nLength - pStream->avail_in ); m_pInflateBuffer->Remove( m_pInflateBuffer->m_nLength - pStream->avail_in ); } } if ( m_nInflateRead >= m_nInflateLength ) { inflateEnd( pStream ); delete pStream; m_pInflatePtr = NULL; m_pInflateBuffer->Clear(); } m_pSource->SetValid(); return SendFragmentRequests(); }
BOOL CDownloadTransferBT::OnRun() { DWORD tNow = GetTickCount(); BOOL bShowInterest = ( tNow - m_tRunThrottle >= 2000 ); QWORD nBlockSize = m_pDownload->m_pTorrent.m_nBlockSize; DWORD nBlockCount = m_pDownload->m_pTorrent.m_nBlockCount; if ( ! m_bAvailable && nBlockSize && nBlockCount && m_nAvailable ) { m_bAvailable = TRUE; if ( m_nAvailable != nBlockCount ) { BYTE* pAvailable = m_pAvailable; DWORD nAvailable = m_nAvailable; m_nAvailable = nBlockCount; m_pAvailable = new BYTE[ nBlockCount ]; ZeroMemory( m_pAvailable, nBlockCount ); if ( pAvailable && nAvailable ) { if ( nAvailable > nBlockCount ) nAvailable = nBlockCount; memcpy( m_pAvailable, pAvailable, nAvailable ); } delete [] pAvailable; } for ( DWORD nBlock = 0; nBlock < nBlockCount; nBlock++ ) { if ( m_pAvailable[ nBlock ] ) { QWORD nOffset = nBlockSize * nBlock; QWORD nLength = min( nBlockSize, m_pDownload->m_nSize - nOffset ); m_pSource->m_oAvailable.insert( m_pSource->m_oAvailable.end(), Fragments::Fragment( nOffset, nOffset + nLength ) ); } } bShowInterest = TRUE; } if ( bShowInterest ) { m_tRunThrottle = tNow; ShowInterest(); if ( m_nState == dtsTorrent || m_nState == dtsRequesting || m_nState == dtsDownloading ) { SendFragmentRequests(); } } if ( ( m_pDownload->GetSourceCount() < Settings.Downloads.SourcesWanted ) && ( tNow >= m_tSourceRequest + Settings.BitTorrent.SourceExchangePeriod * 60 * 1000 ) ) { m_tSourceRequest = tNow; m_pClient->SendSourceRequest(); } return CDownloadTransfer::OnRun(); }