Example #1
0
CBuffer* CDownloadTask::IsPreviewAnswerValid() const
{
	if ( m_nTask != dtaskPreviewRequest || ! m_pRequest->IsFinished() )
		return NULL;

	m_pRequest->GetStatusCode();

	if ( m_pRequest->GetStatusSuccess() == FALSE )
	{
		theApp.Message( MSG_DEBUG, L"Preview failed: HTTP status code %i", m_pRequest->GetStatusCode() );
		return NULL;
	}

	CString strURN = m_pRequest->GetHeader( L"X-Previewed-URN" );

	if ( ! strURN.IsEmpty() )
	{
		Hashes::Sha1Hash oSHA1;
		bool bValid = true;

		if ( m_pDownload )
		{
			if ( oSHA1.fromUrn( strURN ) && validAndUnequal( oSHA1, m_pDownload->m_oSHA1 ) )
				bValid = false;
		}
		else
		{
			CSingleLock oLock( &Library.m_pSection, TRUE );
			CLibraryFile* pFile = LibraryMaps.LookupFileBySHA1( oSHA1 );
			if ( pFile == NULL )
				bValid = false;
			oLock.Unlock();
		}
		if ( ! bValid )
		{
			theApp.Message( MSG_DEBUG, L"Preview failed: wrong URN." );
			return NULL;
		}
	}

	CString strMIME = m_pRequest->GetHeader( L"Content-Type" );

	if ( strMIME.CompareNoCase( L"image/jpeg" ) != 0 )
	{
		theApp.Message( MSG_DEBUG, L"Preview failed: unacceptable content type." );
		return NULL;
	}

	return m_pRequest->GetResponseBuffer();
}
BOOL CDownloadTransferED2K::OnHashsetAnswer(CEDPacket* pPacket)
{
	if ( m_nState != dtsHashset ) return TRUE;
	
    if ( pPacket->GetRemaining() < Hashes::Ed2kHash::byteCount + 2 )
	{
		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 ) )
	{
		return TRUE;	// Hack
//		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_HASHSET_ERROR, (LPCTSTR)m_sAddress );
//		Close( TRI_FALSE );
//		return FALSE;
	}
	
	m_bHashset = TRUE;
	
	DWORD nBlocks = pPacket->ReadShortLE();
	bool bNullBlock = ( m_pDownload->m_nSize % ED2K_PART_SIZE == 0 && m_pDownload->m_nSize );
	QWORD nBlocksFromSize = ( m_pDownload->m_nSize + ED2K_PART_SIZE - 1 ) / ED2K_PART_SIZE;

	if ( bNullBlock )
		nBlocksFromSize++;
	
	if ( nBlocks == 0 ) nBlocks = 1;
	
	if ( nBlocks != nBlocksFromSize )
	{
		theApp.Message( MSG_ERROR, IDS_DOWNLOAD_HASHSET_ERROR, (LPCTSTR)m_sAddress );
	}
	else if ( m_pDownload->SetHashset(	pPacket->m_pBuffer + pPacket->m_nPosition,
										pPacket->GetRemaining() ) )
	{
		return SendSecondaryRequest();
	}
	
	Close( TRI_FALSE );
	return FALSE;
}
Example #3
0
CBuffer* CDownloadTask::IsPreviewAnswerValid(const Hashes::Sha1Hash& oRequestedSHA1) const
{
	if ( m_nTask != dtaskPreviewRequest || ! m_pRequest->IsFinished() )
		return NULL;

	m_pRequest->GetStatusCode();

	if ( m_pRequest->GetStatusSuccess() == FALSE )
	{
		theApp.Message( MSG_DEBUG, L"Preview failed: HTTP status code %i", m_pRequest->GetStatusCode() );
		return NULL;
	}

	const CString strURN = m_pRequest->GetHeader( L"X-Previewed-URN" );
	if ( ! strURN.IsEmpty() )
	{
		Hashes::Sha1Hash oSHA1;
		if ( oSHA1.fromUrn( strURN ) )
		{
			if ( oRequestedSHA1 && validAndUnequal( oSHA1, oRequestedSHA1 ) )
			{
				theApp.Message( MSG_DEBUG, L"Preview failed: Wrong URN." );
				return NULL;
			}
			else if ( ! LibraryMaps.LookupFileBySHA1( oSHA1 ) )
			{
				theApp.Message( MSG_DEBUG, L"Preview failed: Not Found." );
				return NULL;
			}
		}
	}

	const CString strMIME = m_pRequest->GetHeader( L"Content-Type" );
	if ( strMIME.CompareNoCase( L"image/jpeg" ) != 0 )
	{
		theApp.Message( MSG_DEBUG, L"Preview failed: Unacceptable content type." );
		return NULL;
	}

	return m_pRequest->GetResponseBuffer();
}
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 CDownloadTransferED2K::OnFileStatus(CEDPacket* pPacket)
{
	if ( m_nState <= dtsConnecting )
		return TRUE;

	if ( pPacket->GetRemaining() < Hashes::Ed2kHash::byteCount + 2 )
	{
		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() );
		return TRUE;
	}

	DWORD nBlocks = pPacket->ReadShortLE();

	if ( nBlocks == (DWORD)( ( m_pDownload->m_nSize + ED2K_PART_SIZE - 1 ) / ED2K_PART_SIZE ) )
	{
		m_pSource->m_oAvailable.clear();

		delete [] m_pAvailable;
		m_pAvailable = new BYTE[ nBlocks ];
		ZeroMemory( m_pAvailable, nBlocks );

		for ( DWORD nBlock = 0 ; nBlock < nBlocks && pPacket->GetRemaining() ; )
		{
			BYTE nByte = pPacket->ReadByte();

			for ( int nBit = 0 ; nBit < 8 && nBlock < nBlocks ; nBit++, nBlock++ )
			{
				if ( nByte & ( 1 << nBit ) )
				{
					QWORD nFrom = ED2K_PART_SIZE * nBlock;
					QWORD nTo = nFrom + ED2K_PART_SIZE;
					nTo = min( nTo, m_pDownload->m_nSize );

					m_pSource->m_oAvailable.insert( m_pSource->m_oAvailable.end(), Fragments::Fragment( nFrom, nTo ) );
					m_pAvailable[ nBlock ] = TRUE;
				}
			}
		}
	}
	else if ( nBlocks == 0 )
	{
		m_pSource->m_oAvailable.clear();

		delete [] m_pAvailable;
		m_pAvailable = NULL;
	}
	else
	{
		theApp.Message( MSG_ERROR, IDS_ED2K_CLIENT_BAD_PACKET, (LPCTSTR)m_sAddress, pPacket->m_nType );
		Close( TRI_FALSE );
		return FALSE;
	}

	SendSecondaryRequest();

	return TRUE;
}
BOOL CDownloadEditPage::OnApply()
{
	if ( ! UpdateData() )
		return FALSE;

	CString strMessage;

	Hashes::Sha1Hash oSHA1;
	Hashes::TigerHash oTiger;
	Hashes::Ed2kHash oED2K;
	Hashes::Md5Hash oMD5;
	Hashes::BtHash oBTH;

	oSHA1.fromString( m_sSHA1 );
	oTiger.fromString( m_sTiger );
	oED2K.fromString( m_sED2K );
	oMD5.fromString( m_sMD5 );
	oBTH.fromString( m_sBTH );

	if ( ! m_sSHA1.IsEmpty() && ! oSHA1 )
	{
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_BAD_HASH ), _T("SHA1") );
		MsgBox( strMessage, MB_ICONEXCLAMATION );
		GetDlgItem( IDC_URN_SHA1 )->SetFocus();
		return FALSE;
	}
	if ( ! m_sTiger.IsEmpty() && ! oTiger )
	{
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_BAD_HASH ), _T("Tiger-Root") );
		MsgBox( strMessage, MB_ICONEXCLAMATION );
		GetDlgItem( IDC_URN_TIGER )->SetFocus();
		return FALSE;
	}
	if ( ! m_sED2K.IsEmpty() && ! oED2K )
	{
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_BAD_HASH ), _T("ED2K") );
		MsgBox( strMessage, MB_ICONEXCLAMATION );
		GetDlgItem( IDC_URN_ED2K )->SetFocus();
		return FALSE;
	}
	if ( ! m_sMD5.IsEmpty() && ! oMD5 )
	{
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_BAD_HASH ), _T("MD5") );
		MsgBox( strMessage, MB_ICONEXCLAMATION );
		GetDlgItem( IDC_URN_MD5 )->SetFocus();
		return FALSE;
	}
	if ( ! m_sBTH.IsEmpty() && ! oBTH )
	{
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_BAD_HASH ), _T("BitTorrent") );
		MsgBox( strMessage, MB_ICONEXCLAMATION );
		GetDlgItem( IDC_URN_BTH )->SetFocus();
		return FALSE;
	}

	CSingleLock pLock( &Transfers.m_pSection );
	if ( ! pLock.Lock( 250 ) )
		return FALSE;

	CDownloadSheet* pSheet = (CDownloadSheet*)GetParent();
	CDownload* pDownload = pSheet->GetDownload();
	if ( ! pDownload )
		return CPropertyPageAdv::OnApply();		// Invalid download

	bool bNeedUpdate = false;
	bool bCriticalChange = false;

	bNeedUpdate	= pDownload->m_bSHA1Trusted ^ ( m_bSHA1Trusted == TRUE );
	bNeedUpdate	|= pDownload->m_bTigerTrusted ^ ( m_bTigerTrusted == TRUE );
	bNeedUpdate	|= pDownload->m_bED2KTrusted ^ ( m_bED2KTrusted == TRUE );
	bNeedUpdate	|= pDownload->m_bMD5Trusted ^ ( m_bMD5Trusted == TRUE );
	bNeedUpdate	|= pDownload->m_bBTHTrusted ^ ( m_bBTHTrusted == TRUE );

	if ( pDownload->m_sName != m_sName )
	{
		pLock.Unlock();
		if ( MsgBox( IDS_DOWNLOAD_EDIT_CHANGE_NAME, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;		// Was IDS_DOWNLOAD_EDIT_RENAME
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->Rename( m_sName );
		bNeedUpdate = true;
	}

	QWORD nNewSize = 0;
	if ( _stscanf( m_sFileSize, _T("%I64u"), &nNewSize ) == 1 && nNewSize != pDownload->m_nSize )
	{
		pLock.Unlock();
		if ( MsgBox( IDS_DOWNLOAD_EDIT_CHANGE_SIZE, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->m_nSize = nNewSize;
		pDownload->CloseTransfers();
		pDownload->ClearVerification();
		bCriticalChange = true;
	}

	SYSTEMTIME tDate;
	m_wndDate.GetTime( &tDate );
	if ( pDownload->m_tDate != tDate )
		pDownload->m_tDate = tDate;

	if ( pDownload->m_oSHA1.isValid() != oSHA1.isValid()
		|| validAndUnequal( pDownload->m_oSHA1, oSHA1 ) )
	{
		pLock.Unlock();
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_CHANGE_HASH ), _T("SHA1"), _T("SHA1") );
		if ( MsgBox( strMessage, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->m_oSHA1 = oSHA1;
		if ( oSHA1 ) pDownload->m_bSHA1Trusted = true;
		pDownload->CloseTransfers();
		pDownload->ClearVerification();
		bCriticalChange = true;
	}

	if ( pDownload->m_oTiger.isValid() != oTiger.isValid()
		|| validAndUnequal( pDownload->m_oTiger, oTiger ) )
	{
		pLock.Unlock();
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_CHANGE_HASH ), _T("Tiger-Root"), _T("Tiger-Root") );
		if ( MsgBox( strMessage, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->m_oTiger = oTiger;
		if ( oTiger ) pDownload->m_bTigerTrusted = true;
		pDownload->CloseTransfers();
		pDownload->ClearVerification();
		bCriticalChange = true;
	}

	if ( pDownload->m_oED2K.isValid() != oED2K.isValid()
		|| validAndUnequal( pDownload->m_oED2K, oED2K ) )
	{
		pLock.Unlock();
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_CHANGE_HASH ), _T("ED2K"), _T("ED2K") );
		if ( MsgBox( strMessage, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->m_oED2K = oED2K;
		if ( oED2K ) pDownload->m_bED2KTrusted = true;
		pDownload->CloseTransfers();
		pDownload->ClearVerification();
		bCriticalChange = true;
	}

	if ( pDownload->m_oMD5.isValid() != oMD5.isValid()
		|| validAndUnequal( pDownload->m_oMD5, oMD5 ) )
	{
		pLock.Unlock();
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_CHANGE_HASH ), _T("MD5"), _T("MD5") );
		if ( MsgBox( strMessage, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->m_oMD5 = oMD5;
		if ( oMD5 ) pDownload->m_bMD5Trusted = true;
		pDownload->CloseTransfers();
		pDownload->ClearVerification();
		bCriticalChange = true;
	}

	if ( pDownload->m_oBTH.isValid() != oBTH.isValid()
		|| validAndUnequal( pDownload->m_oBTH, oBTH ) )
	{
		pLock.Unlock();
		strMessage.Format( LoadString( IDS_DOWNLOAD_EDIT_CHANGE_HASH ), _T("BitTorrent"), _T("BitTorrent") );
		if ( MsgBox( strMessage, MB_ICONQUESTION|MB_YESNO ) != IDYES ) return FALSE;
		pLock.Lock();
		pDownload = pSheet->GetDownload();
		if ( ! pDownload ) return CPropertyPageAdv::OnApply();
		pDownload->m_oBTH = oBTH;
		if ( oBTH ) pDownload->m_bBTHTrusted = true;
		pDownload->CloseTransfers();
		pDownload->ClearVerification();
		bCriticalChange = true;
	}

	pDownload->m_bSHA1Trusted = m_bSHA1Trusted != FALSE;
	pDownload->m_bTigerTrusted = m_bTigerTrusted != FALSE;
	pDownload->m_bED2KTrusted = m_bED2KTrusted != FALSE;
	pDownload->m_bMD5Trusted = m_bMD5Trusted != FALSE;
	pDownload->m_bBTHTrusted = m_bBTHTrusted != FALSE;

	if ( bCriticalChange )
	{
		pDownload->CloseTransfers();
		pDownload->ClearSources();
		pDownload->ClearFailedSources();
		pDownload->ClearVerification();
		bNeedUpdate = true;
	}

	if ( bNeedUpdate )
		pDownload->SetModified();

	return CPropertyPageAdv::OnApply();
}