1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

root/trunk/shareaza/DlgTorrentSeed.cpp @ 6673

Revision 6673, 14.7 KB (checked in by Rolandas, 5 years ago)

Removed single torrent verification from the torrent seed dialog and moved the task to the downlods window

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
  • Property cvs2svn:cvs-rev set to 1.16
Line 
1//
2// DlgTorrentSeed.cpp
3//
4// Copyright (c) Shareaza Development Team, 2002-2007.
5// This file is part of SHAREAZA (shareaza.sourceforge.net)
6//
7// Shareaza is free software; you can redistribute it
8// and/or modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; either version 2 of
10// the License, or (at your option) any later version.
11//
12// Shareaza is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Shareaza; if not, write to the Free Software
19// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20//
21
22#include "StdAfx.h"
23#include "Shareaza.h"
24#include "Settings.h"
25#include "Network.h"
26#include "Library.h"
27#include "SharedFile.h"
28#include "Transfers.h"
29#include "Downloads.h"
30#include "Download.h"
31#include "ShareazaURL.h"
32#include "HttpRequest.h"
33#include "DlgTorrentSeed.h"
34#include "WndMain.h"
35#include "WndDownloads.h"
36#include "DlgHelp.h"
37
38#include "LibraryHistory.h"
39
40#ifdef _DEBUG
41#undef THIS_FILE
42static char THIS_FILE[]=__FILE__;
43#define new DEBUG_NEW
44#endif
45
46IMPLEMENT_DYNAMIC(CTorrentSeedDlg, CSkinDialog)
47
48BEGIN_MESSAGE_MAP(CTorrentSeedDlg, CSkinDialog)
49        ON_BN_CLICKED(IDC_DOWNLOAD, OnDownload)
50        ON_BN_CLICKED(IDC_SEED, OnSeed)
51        ON_WM_DESTROY()
52        ON_WM_TIMER()
53END_MESSAGE_MAP()
54
55const DWORD BUFFER_SIZE = 2 * 1024 * 1024u;
56
57
58/////////////////////////////////////////////////////////////////////////////
59// CTorrentSeedDlg construction
60
61CTorrentSeedDlg::CTorrentSeedDlg(LPCTSTR pszTorrent, BOOL bForceSeed, CWnd* pParent) : CSkinDialog( CTorrentSeedDlg::IDD, pParent )
62{
63        m_hThread       = NULL;
64        m_sTorrent      = pszTorrent;
65        m_bForceSeed    = bForceSeed;
66}
67
68CTorrentSeedDlg::~CTorrentSeedDlg()
69{
70        ASSERT( m_hThread == NULL );
71}
72
73void CTorrentSeedDlg::DoDataExchange(CDataExchange* pDX)
74{
75        CDialog::DoDataExchange( pDX );
76        DDX_Control( pDX, IDC_DOWNLOAD, m_wndDownload );
77        DDX_Control( pDX, IDC_SEED, m_wndSeed );
78        DDX_Control( pDX, IDC_PROGRESS, m_wndProgress );
79}
80
81/////////////////////////////////////////////////////////////////////////////
82// CTorrentSeedDlg message handlers
83
84BOOL CTorrentSeedDlg::OnInitDialog()
85{
86        CSkinDialog::OnInitDialog();
87       
88        SkinMe( NULL, IDR_MAINFRAME );
89       
90        if ( Settings.General.LanguageRTL ) m_wndProgress.ModifyStyleEx( WS_EX_LAYOUTRTL, 0, 0 );
91        m_wndProgress.SetRange( 0, 1000 );
92        m_wndProgress.SetPos( 0 );
93       
94        if ( m_bForceSeed )
95        {
96                m_wndDownload.EnableWindow( FALSE );
97                if ( Settings.BitTorrent.AutoSeed ) PostMessage( WM_TIMER, 4 );
98
99        }
100        // if ( m_bForceSeed ) m_wndDownload.ShowWindow( SW_HIDE );
101
102        return TRUE;
103}
104
105void CTorrentSeedDlg::OnDownload()
106{
107        /*CWnd* pWnd =*/ AfxGetMainWnd();
108        CBTInfo* pTorrent = new CBTInfo();
109       
110        if ( pTorrent->LoadTorrentFile( m_sTorrent ) )
111        {
112                if ( pTorrent->HasEncodingError() )             // Check the torrent is valid
113                {
114                        CHelpDlg::Show( _T("GeneralHelp.BadTorrentEncoding") );
115                }
116
117                CShareazaURL* pURL = new CShareazaURL( pTorrent );
118                //if ( ! pWnd->PostMessage( WM_URL, (WPARAM)pURL ) ) delete pURL;
119                CLibraryFile* pFile;
120               
121
122                CSingleLock oLibraryLock( &Library.m_pSection, TRUE );
123                if ( ( pFile = LibraryMaps.LookupFileBySHA1( pURL->m_oSHA1 ) ) != NULL
124                        || ( pFile = LibraryMaps.LookupFileByED2K( pURL->m_oED2K ) ) != NULL
125                        || ( pFile = LibraryMaps.LookupFileByBTH( pURL->m_oBTH ) ) != NULL
126                        || ( pFile = LibraryMaps.LookupFileByMD5( pURL->m_oMD5 ) ) != NULL )
127                {
128                        CString strFormat, strMessage;
129                        LoadString( strFormat, IDS_URL_ALREADY_HAVE );
130                        strMessage.Format( strFormat, (LPCTSTR)pFile->m_sName );
131                        oLibraryLock.Unlock();
132                                       
133                        if ( AfxMessageBox( strMessage, MB_ICONINFORMATION|MB_YESNOCANCEL|MB_DEFBUTTON2 ) == IDNO )
134                        {
135                                delete pURL;
136                                EndDialog( IDOK );
137                                return;
138                        }
139                }
140                else
141                {
142                        oLibraryLock.Unlock();
143                }
144                       
145                CDownload* pDownload = Downloads.Add( pURL );
146
147                // Downloads.Add() took a copy of the CBTInfo, so we need to delete the original
148                delete pURL;
149                       
150                if ( pDownload == NULL )                       
151                {
152                        EndDialog( IDOK );
153                        return;
154                }
155                       
156                if ( ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) == 0 )
157                {               
158                        if ( ! Network.IsWellConnected() ) Network.Connect( TRUE );
159                }
160
161                CMainWnd* pMainWnd = (CMainWnd*)AfxGetMainWnd();
162                pMainWnd->m_pWindows.Open( RUNTIME_CLASS(CDownloadsWnd) );
163                               
164                if ( Settings.Downloads.ShowMonitorURLs )
165                {
166                        CSingleLock pTransfersLock( &Transfers.m_pSection, TRUE );
167                        if ( Downloads.Check( pDownload ) ) pDownload->ShowMonitor( &pTransfersLock );
168                }
169
170                EndDialog( IDOK );
171                return;
172        }
173        else
174                delete pTorrent;
175        theApp.Message( MSG_DISPLAYED_ERROR, IDS_BT_PREFETCH_ERROR, (LPCTSTR)m_sTorrent );
176        EndDialog( IDOK );
177}
178
179void CTorrentSeedDlg::OnSeed()
180{
181        m_wndDownload.EnableWindow( FALSE );
182        m_wndSeed.EnableWindow( FALSE );
183        m_bCancel = FALSE;
184       
185        if ( m_pInfo.LoadTorrentFile( m_sTorrent ) )
186        {
187                if ( m_pInfo.HasEncodingError() )               // Check the torrent is valid
188                {
189                        CHelpDlg::Show( _T("GeneralHelp.BadTorrentEncoding") );
190                }
191                if ( Downloads.FindByBTH( m_pInfo.m_oBTH ) == NULL )
192                {
193                        // Connect if (we aren't)
194                        if ( ! Network.IsConnected() ) Network.Connect();
195
196                        // Update the last seeded torrent
197                        CSingleLock pLock( &Library.m_pSection );
198                        if ( pLock.Lock( 250 ) )
199                        {
200                                LibraryHistory.LastSeededTorrent.m_sName                = m_pInfo.m_sName.Left( 40 );
201                                LibraryHistory.LastSeededTorrent.m_sPath = m_sTorrent;
202                                LibraryHistory.LastSeededTorrent.m_tLastSeeded = static_cast< DWORD >( time( NULL ) );
203
204                                // If it's a 'new' torrent, reset the counters
205                                if ( !validAndEqual( LibraryHistory.LastSeededTorrent.m_oBTH, m_pInfo.m_oBTH ) )
206                                {
207                                        LibraryHistory.LastSeededTorrent.m_nUploaded    = 0;
208                                        LibraryHistory.LastSeededTorrent.m_nDownloaded  = 0;
209                                        LibraryHistory.LastSeededTorrent.m_oBTH                 = m_pInfo.m_oBTH;
210                                }
211                        }
212
213                        // Start the torrent seed process
214                        m_hThread = BeginThread( "DlgTorrentSeed", ThreadStart, this );
215                }
216                else    // We are already seeding the torrent
217                {
218                        CString strFormat, strMessage;
219                        LoadString(strFormat, IDS_BT_SEED_ALREADY );
220                        strMessage.Format( strFormat, (LPCTSTR)m_pInfo.m_sName );
221                        AfxMessageBox( strMessage, MB_ICONEXCLAMATION );
222                        EndDialog( IDOK );
223                }
224        }
225        else
226        {
227                // We couldn't load the .torrent file
228                CString strFormat, strMessage;
229                LoadString(strFormat, IDS_BT_SEED_PARSE_ERROR );
230                strMessage.Format( strFormat, (LPCTSTR)m_sTorrent );
231                AfxMessageBox( strMessage, MB_ICONEXCLAMATION );
232                EndDialog( IDOK );
233        }
234}
235
236void CTorrentSeedDlg::OnCancel()
237{
238        if ( m_wndDownload.IsWindowEnabled() || m_bCancel )
239        {
240                CSkinDialog::OnCancel();
241        }
242        else
243        {
244                m_bCancel = TRUE;
245        }
246}
247
248void CTorrentSeedDlg::OnDestroy()
249{
250        if ( m_hThread != NULL )
251        {
252                m_bCancel = TRUE;
253                CloseThread( &m_hThread );
254        }
255       
256        CSkinDialog::OnDestroy();
257}
258
259void CTorrentSeedDlg::OnTimer(UINT_PTR nIDEvent)
260{
261        CSkinDialog::OnTimer( nIDEvent );
262       
263        if ( nIDEvent == 1 )
264        {
265                EndDialog( IDOK );
266        }
267        else if ( nIDEvent == 2 )
268        {
269                if ( m_bCancel == FALSE ) AfxMessageBox( m_sMessage, MB_ICONEXCLAMATION );
270                EndDialog( IDCANCEL );
271        }
272        else if ( nIDEvent == 3 )
273        {
274                if ( m_nScaled != m_nOldScaled )
275                {
276                        m_nOldScaled = m_nScaled;
277                        m_wndProgress.SetPos( m_nScaled );
278                }
279        }
280        else if ( nIDEvent == 4 )
281        {
282                OnSeed();
283        }
284}
285
286/////////////////////////////////////////////////////////////////////////////
287// CTorrentSeedDlg thread run
288
289UINT CTorrentSeedDlg::ThreadStart(LPVOID pParam)
290{
291        ((CTorrentSeedDlg*)pParam)->OnRun();
292        return 0;
293}
294
295void CTorrentSeedDlg::OnRun()
296{
297        if ( m_pInfo.m_nFiles == 1 )
298        {
299                RunSingleFile();
300        }
301        else
302        {
303                RunMultiFile();
304        }
305}
306
307void CTorrentSeedDlg::RunSingleFile()
308{
309        m_sTarget = FindFile( &m_pInfo.m_pFiles[0] );
310       
311        if ( m_sTarget.IsEmpty() || GetFileAttributes( m_sTarget ) == INVALID_FILE_ATTRIBUTES )
312        {
313                CString strFormat;
314                LoadString(strFormat, IDS_BT_SEED_SOURCE_LOST );
315                m_sMessage.Format( strFormat, (LPCTSTR)m_pInfo.m_pFiles[0].m_sPath );
316                PostMessage( WM_TIMER, 2 );
317                return;
318        }
319       
320        if ( CreateDownload() )
321        {
322                PostMessage( WM_TIMER, 1 );
323        }
324        else
325        {
326                PostMessage( WM_TIMER, 2 );
327        }
328}
329
330void CTorrentSeedDlg::RunMultiFile()
331{
332        HANDLE hTarget = CreateTarget();
333       
334        if ( hTarget != INVALID_HANDLE_VALUE )
335        {
336                BOOL bBuild = BuildFiles( hTarget );
337                CloseHandle( hTarget );
338               
339                if ( bBuild && CreateDownload() )
340                {
341                        PostMessage( WM_TIMER, 1 );
342                }
343                else
344                {
345                        DeleteFile( m_sTarget );
346                        PostMessage( WM_TIMER, 2 );
347                }
348        }
349        else
350        {
351                PostMessage( WM_TIMER, 2 );
352        }
353}
354
355CString CTorrentSeedDlg::FindFile(LPVOID pVoid)
356{
357        CBTInfo::CBTFile* pFile = reinterpret_cast<CBTInfo::CBTFile*>(pVoid);
358        CString strFile;
359       
360        CString strPath = m_sTorrent;
361        int nSlash = strPath.ReverseFind( '\\' );
362        if ( nSlash >= 0 ) strPath = strPath.Left( nSlash + 1 );
363
364        if ( pFile->m_oSHA1 )
365        {
366                CSingleLock oLibraryLock( &Library.m_pSection, TRUE );
367                if ( CLibraryFile* pShared = LibraryMaps.LookupFileBySHA1( pFile->m_oSHA1, FALSE, TRUE ) )
368                {
369                        strFile = pShared->GetPath();
370                        oLibraryLock.Unlock();
371                        if ( GetFileAttributes( strFile ) != INVALID_FILE_ATTRIBUTES ) return strFile;
372                }
373        }
374
375        strFile = Settings.Downloads.CompletePath + "\\" + pFile->m_sPath;
376        if ( GetFileAttributes( strFile ) != INVALID_FILE_ATTRIBUTES ) return strFile;
377
378        strFile = strPath + pFile->m_sPath;
379        if ( GetFileAttributes( strFile ) != INVALID_FILE_ATTRIBUTES ) return strFile;
380       
381        //Try removing the outer directory in case of multi-file torrent oddities
382        LPCTSTR pszName = _tcsrchr( pFile->m_sPath, '\\' );
383        if ( pszName == NULL ) pszName = pFile->m_sPath; else pszName ++;
384
385        strFile = Settings.Downloads.CompletePath + "\\" + pszName;
386        if ( GetFileAttributes( strFile ) != INVALID_FILE_ATTRIBUTES ) return strFile;
387
388        strFile = strPath + pszName;
389        if ( GetFileAttributes( strFile ) != INVALID_FILE_ATTRIBUTES ) return strFile;
390
391        strFile.Empty();
392        return strFile;
393}
394
395HANDLE CTorrentSeedDlg::CreateTarget()
396{
397        m_sTarget = Settings.Downloads.IncompletePath + '\\';
398        m_sTarget += m_pInfo.m_oBTH.toString< Hashes::base16Encoding >();
399       
400        HANDLE hTarget = CreateFile( m_sTarget, GENERIC_WRITE, 0, NULL, CREATE_NEW,
401                FILE_ATTRIBUTE_NORMAL, NULL );
402        VERIFY_FILE_ACCESS( hTarget, m_sTarget )
403        if ( hTarget == INVALID_HANDLE_VALUE )
404        {
405                CString strFormat;
406                LoadString(strFormat, IDS_BT_SEED_CREATE_FAIL );
407                m_sMessage.Format( strFormat, (LPCTSTR)m_sTarget );
408        }
409       
410        return hTarget;
411}
412
413BOOL CTorrentSeedDlg::BuildFiles(HANDLE hTarget)
414{
415        m_nVolume = m_nTotal = 0;
416        m_nScaled = m_nOldScaled = 0;
417       
418        for ( int nFile = 0 ; nFile < m_pInfo.m_nFiles ; nFile++ )
419        {
420                CBTInfo::CBTFile* pFile = &m_pInfo.m_pFiles[ nFile ];
421                m_nTotal += pFile->m_nSize;
422        }
423       
424        m_pInfo.BeginBlockTest();
425        m_nBlockNumber  = 0;
426        m_nBlockLength  = m_pInfo.m_nBlockSize;
427       
428        for ( int nFile = 0 ; nFile < m_pInfo.m_nFiles ; nFile++ )
429        {
430                CBTInfo::CBTFile* pFile = &m_pInfo.m_pFiles[ nFile ];
431                CString strSource = FindFile( pFile );
432                HANDLE hSource = INVALID_HANDLE_VALUE;
433               
434                if ( strSource.GetLength() > 0 )
435                {
436                        hSource = CreateFile( strSource, GENERIC_READ,
437                                FILE_SHARE_READ | ( theApp.m_bNT ? FILE_SHARE_DELETE : 0 ),
438                                NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
439                        VERIFY_FILE_ACCESS( hSource, strSource )
440                }
441               
442                if ( hSource == INVALID_HANDLE_VALUE )
443                {
444                        CString strFormat;
445                        LoadString(strFormat, IDS_BT_SEED_SOURCE_LOST );
446                        m_sMessage.Format( strFormat, (LPCTSTR)pFile->m_sPath );
447                        return FALSE;
448                }
449               
450                DWORD nSizeHigh = 0;
451                DWORD nSizeLow  = GetFileSize( hSource, &nSizeHigh );
452                QWORD nSize             = (QWORD)nSizeLow + ( (QWORD)nSizeHigh << 32 );
453               
454                if ( nSize != pFile->m_nSize )
455                {
456                        CloseHandle( hSource );
457                        m_sMessage.Format( IDS_BT_SEED_SOURCE_SIZE,
458                                pFile->m_sPath,
459                                Settings.SmartVolume( pFile->m_nSize ),
460                                Settings.SmartVolume( nSize ) );
461                        return FALSE;
462                }
463               
464                BOOL bSuccess = CopyFile( hTarget, hSource, pFile->m_nSize, pFile->m_sPath );
465               
466                CloseHandle( hSource );
467               
468                if ( m_bCancel || ! bSuccess ) return FALSE;
469        }
470       
471        return VerifyData( NULL, 0, m_pInfo.m_pFiles[ m_pInfo.m_nFiles - 1 ].m_sPath );
472}
473
474BOOL CTorrentSeedDlg::CopyFile(HANDLE hTarget, HANDLE hSource, QWORD nLength, LPCTSTR pszPath)
475{
476        auto_array< BYTE > pBuffer( new BYTE[ BUFFER_SIZE ] );
477       
478        while ( nLength )
479        {
480                DWORD nBuffer   = min( nLength, BUFFER_SIZE );
481                DWORD nSuccess  = 0;
482                DWORD tStart    = GetTickCount();
483               
484                if ( ! ReadFile( hSource, pBuffer.get(), nBuffer, &nBuffer, NULL ) ||
485                         ! VerifyData( pBuffer.get(), nBuffer, pszPath ) ||
486                         ! WriteFile( hTarget, pBuffer.get(), nBuffer, &nSuccess, NULL ) )
487                {
488                        return FALSE;
489                }
490
491                if ( nSuccess == nBuffer )
492                {
493                        nLength -= nBuffer;
494                }
495                else
496                {
497                        break;
498                }
499               
500                m_nVolume += nBuffer;
501                m_nScaled = (int)( (double)m_nVolume / (double)m_nTotal * 1000.0f );
502                if ( m_nScaled != m_nOldScaled ) PostMessage( WM_TIMER, 3 );
503               
504                if ( m_bCancel ) break;
505                tStart = ( GetTickCount() - tStart ) / 2;
506                Sleep( min( tStart, 50ul ) );
507                if ( m_bCancel ) break;
508        }
509       
510        if ( nLength == 0 )
511        {
512                return TRUE;
513        }
514        else
515        {
516                CString strFormat;
517                LoadString(strFormat, IDS_BT_SEED_COPY_FAIL );
518                m_sMessage.Format( strFormat, (LPCTSTR)pszPath );
519                return FALSE;
520        }
521}
522
523BOOL CTorrentSeedDlg::VerifyData(BYTE* pBuffer, DWORD nLength, LPCTSTR pszPath)
524{
525        if ( pBuffer == NULL )
526        {
527                if ( m_nBlockNumber >= m_pInfo.m_nBlockCount ) return TRUE;
528                if ( m_pInfo.FinishBlockTest( m_nBlockNumber++ ) ) return TRUE;
529               
530                CString strFormat;
531                LoadString(strFormat, IDS_BT_SEED_VERIFY_FAIL );
532                m_sMessage.Format( strFormat, (LPCTSTR)pszPath );
533                return FALSE;
534        }
535       
536        while ( nLength > 0 )
537        {
538                DWORD nBlock = min( nLength, m_nBlockLength );
539               
540                m_pInfo.AddToTest( pBuffer, nBlock );
541               
542                pBuffer += nBlock;
543                nLength -= nBlock;
544                m_nBlockLength -= nBlock;
545               
546                if ( m_nBlockLength == 0 )
547                {
548                        if ( ! m_pInfo.FinishBlockTest( m_nBlockNumber++ ) )
549                        {
550                                CString strFormat;
551                                LoadString(strFormat, IDS_BT_SEED_VERIFY_FAIL );
552                                m_sMessage.Format( strFormat, (LPCTSTR)pszPath );
553                                return FALSE;
554                        }
555                       
556                        if ( m_nBlockNumber < m_pInfo.m_nBlockCount )
557                        {
558                                m_nBlockLength = m_pInfo.m_nBlockSize;
559                                m_pInfo.BeginBlockTest();
560                        }
561                }
562        }
563       
564        return TRUE;
565}
566
567BOOL CTorrentSeedDlg::CreateDownload()
568{
569        CSingleLock pTransfersLock( &Transfers.m_pSection );
570        if ( ! pTransfersLock.Lock( 2000 ) ) return FALSE;
571       
572        if ( Downloads.FindByBTH( m_pInfo.m_oBTH ) != NULL )
573        {
574                CString strFormat;
575                LoadString(strFormat, IDS_BT_SEED_ALREADY );
576                m_sMessage.Format( strFormat, (LPCTSTR)m_pInfo.m_sName );
577                return FALSE;
578        }
579       
580        CBTInfo* pInfo = new CBTInfo();
581        pInfo->Copy( &m_pInfo );
582        CShareazaURL pURL( pInfo );
583        CDownload* pDownload = Downloads.Add( &pURL );
584       
585        if ( pDownload != NULL && pDownload->SeedTorrent( m_sTarget ) )
586        {
587                if ( pInfo->m_nFiles == 1 )
588                {
589                        pDownload->MakeComplete();
590                        pDownload->ResetVerification();
591                        pDownload->SetModified();
592                }
593                return TRUE;
594        }
595        else
596        {
597                CString strFormat;
598                LoadString(strFormat, IDS_BT_SEED_ERROR );
599                m_sMessage.Format( strFormat, (LPCTSTR)m_pInfo.m_sName );
600                return FALSE;
601        }
602}
Note: See TracBrowser for help on using the browser.