00001
00002
00003
00004
00005
00006 #include "stdafx.h"
00007 #include "FdmApp.h"
00008 #include "vmsBtDownloadManager.h"
00009
00010 #ifdef _DEBUG
00011 #undef THIS_FILE
00012 static char THIS_FILE[]=__FILE__;
00013 #define new DEBUG_NEW
00014 #endif
00015
00016 vmsBtDownloadManager::vmsBtDownloadManager()
00017 {
00018 m_pDownload = NULL;
00019 m_pTorrent = NULL;
00020 m_info.pbFastResumeData = NULL;
00021 m_info.dwFastResumeDataSize = 0;
00022 m_pfnEvHandler = NULL;
00023 m_info.dwFlags = 0;
00024 m_info.pfProgress = NULL;
00025 m_info.timeLastDataStatAccess.Now ();
00026 m_bStoppedByUser = FALSE;
00027 m_bThreadRunning = m_bThreadDoJob = m_bThreadNeedStop = false;
00028 m_info.nUploadedBytes = 0;
00029 m_info.fShareRating = 0;
00030 m_info.nWastedBytes = 0;
00031 m_info.fPercentDone = 0;
00032 m_info.bDone = FALSE;
00033 m_info.nDownloadedBytes = 0;
00034 m_nUsingBtDownload = 0;
00035
00036 m_uTrafficLimit = UINT_MAX;
00037 m_uLowSpeedMaxTime = UINT_MAX;
00038
00039 if (_App.Bittorrent_DisableSeedingByDef ())
00040 enable_Flags (BTDF_DISABLE_SEEDING);
00041 }
00042
00043 vmsBtDownloadManager::~vmsBtDownloadManager()
00044 {
00045 DeleteBtDownload ();
00046 SAFE_RELEASE (m_pTorrent);
00047 SAFE_DELETE_ARRAY (m_info.pbFastResumeData);
00048 SAFE_DELETE_ARRAY (m_info.pfProgress);
00049 }
00050
00051 BOOL vmsBtDownloadManager::CreateByTorrentFile(LPCSTR pszTorrentFile, LPCSTR pszOutputPath, LPCSTR pszTorrentUrl)
00052 {
00053 ASSERT (m_pTorrent == NULL);
00054 if (m_pTorrent)
00055 return FALSE;
00056
00057 m_pTorrent = _BT.CreateTorrentFileObject ();
00058
00059 if (FALSE == m_pTorrent->LoadFromFile (pszTorrentFile))
00060 {
00061 m_pTorrent->Release ();
00062 m_pTorrent = NULL;
00063 return FALSE;
00064 }
00065
00066 m_info.strTorrentUrl = pszTorrentUrl;
00067 m_info.strOutputPath = pszOutputPath;
00068 if (m_info.strOutputPath [m_info.strOutputPath.GetLength () - 1] != '\\')
00069 m_info.strOutputPath += '\\';
00070
00071 PostCreateTorrentObject ();
00072
00073 return TRUE;
00074 }
00075
00076 BOOL vmsBtDownloadManager::CreateBtDownload()
00077 {
00078 if (m_pDownload)
00079 return TRUE;
00080
00081 vmsBtSession *pSession = _BT.get_Session ();
00082 if (pSession == NULL)
00083 return FALSE;
00084
00085 CString strOutputPath = m_info.strOutputPath;
00086 ProcessFilePathMacroses (strOutputPath);
00087
00088 m_pDownload = pSession->CreateDownload (m_pTorrent, strOutputPath,
00089 m_info.pbFastResumeData, m_info.dwFastResumeDataSize,
00090 (m_info.dwFlags & BTDF_RESERVE_DISK_SPACE) == 0);
00091
00092 if (m_pDownload == NULL)
00093 return FALSE;
00094
00095 return TRUE;
00096 }
00097
00098 void vmsBtDownloadManager::ProcessFilePathMacroses(CString &str)
00099 {
00100 ASSERT (m_pTorrent != NULL);
00101
00102 if (str.Find ('%', 0) == -1)
00103 return;
00104
00105 char szTracker [10000];
00106 m_pTorrent->get_TrackerUrl (szTracker, 0);
00107 fsURL url;
00108 url.Crack (szTracker);
00109
00110 str.Replace ("%server%", url.GetHostName ());
00111 str.Replace ("%path_on_server%", url.GetPath ());
00112
00113 str.Replace ("/", "\\");
00114 str.Replace ("\\\\", "\\");
00115
00116 SYSTEMTIME st;
00117 GetLocalTime (&st);
00118
00119 str.Replace ("%date%", "%year%-%month%-%day%");
00120
00121 CString strY, strM, strD;
00122 strY.Format ("%04d", (int)st.wYear);
00123 strM.Format ("%02d", (int)st.wMonth);
00124 strD.Format ("%02d", (int)st.wDay);
00125
00126 str.Replace ("%year%", strY);
00127 str.Replace ("%month%", strM);
00128 str.Replace ("%day%", strD);
00129 }
00130
00131 void vmsBtDownloadManager::DeleteBtDownload()
00132 {
00133 if (m_pDownload)
00134 {
00135 vmsBtDownload *p = m_pDownload;
00136 while (m_nUsingBtDownload)
00137 Sleep (0);
00138 m_pDownload = NULL;
00139 _BT.get_Session ()->DeleteDownload (p);
00140 }
00141 }
00142
00143 vmsBtDownloadStateEx vmsBtDownloadManager::get_State()
00144 {
00145 InterlockedIncrement (&m_nUsingBtDownload);
00146 vmsBtDownloadStateEx enState = m_pDownload ?
00147 (vmsBtDownloadStateEx) m_pDownload->GetState () : BTDSE_STOPPED;
00148 InterlockedDecrement (&m_nUsingBtDownload);
00149 return enState;
00150 }
00151
00152 fsString vmsBtDownloadManager::get_TorrentName()
00153 {
00154 ASSERT (m_pTorrent != NULL);
00155 char sz [10000] = "";
00156 m_pTorrent->get_TorrentName (sz);
00157 vmsUtf8ToAscii (sz);
00158 return sz;
00159 }
00160
00161 UINT vmsBtDownloadManager::GetUploadSpeed()
00162 {
00163 InterlockedIncrement (&m_nUsingBtDownload);
00164 BOOL b = m_pDownload ? m_pDownload->GetUploadSpeed () : 0;
00165 InterlockedDecrement (&m_nUsingBtDownload);
00166 return b;
00167 }
00168
00169 int vmsBtDownloadManager::get_FileCount()
00170 {
00171 ASSERT (m_pTorrent != NULL);
00172 return m_pTorrent->get_FileCount ();
00173 }
00174
00175 fsString vmsBtDownloadManager::get_OutputFilePathName(int nIndex)
00176 {
00177 ASSERT (m_pTorrent != NULL);
00178 fsString str = get_OutputPath ();
00179 if (str [str.GetLength () - 1] != '\\')
00180 str += '\\';
00181 str += get_FileName (nIndex);
00182 return str;
00183 }
00184
00185 LPCSTR vmsBtDownloadManager::get_OutputPath()
00186 {
00187 return m_info.strOutputPath;
00188 }
00189
00190 void vmsBtDownloadManager::SetEventsHandler(fntBtDownloadManagerEventHandler pfn, LPVOID pData)
00191 {
00192 m_pfnEvHandler = pfn;
00193 m_lpEvParam = pData;
00194 }
00195
00196 fsString vmsBtDownloadManager::get_InfoHash()
00197 {
00198 ASSERT (m_pTorrent != NULL);
00199 char sz [1000] = "";
00200 m_pTorrent->get_InfoHash (sz);
00201 return sz;
00202 }
00203
00204 LPCSTR vmsBtDownloadManager::get_TorrentUrl()
00205 {
00206 return m_info.strTorrentUrl.IsEmpty () ? "" : m_info.strTorrentUrl;
00207 }
00208
00209 void vmsBtDownloadManager::get_TrackerLogin(fsString &strUser, fsString &strPassword)
00210 {
00211 strUser = m_info.strTrackerUser;
00212 strPassword = m_info.strTrackerPassword;
00213 }
00214
00215 fsString vmsBtDownloadManager::get_URL()
00216 {
00217 return get_TorrentUrl ();
00218 }
00219
00220 DWORD vmsBtDownloadManager::get_Flags()
00221 {
00222 return m_info.dwFlags;
00223 }
00224
00225 void vmsBtDownloadManager::enable_Flags(DWORD dw)
00226 {
00227 m_info.dwFlags |= dw;
00228 }
00229
00230 void vmsBtDownloadManager::disable_Flags(DWORD dw)
00231 {
00232 m_info.dwFlags &= ~dw;
00233 }
00234
00235 void vmsBtDownloadManager::set_TrackerLogin(LPCSTR pszUser, LPCSTR pszPassword)
00236 {
00237 m_info.strTrackerUser = pszUser;
00238 m_info.strTrackerPassword = pszPassword;
00239 InterlockedIncrement (&m_nUsingBtDownload);
00240 if (m_pDownload)
00241 m_pDownload->set_TrackerLogin (pszUser, pszPassword);
00242 InterlockedDecrement (&m_nUsingBtDownload);
00243 }
00244
00245 fsString vmsBtDownloadManager::get_TorrentComment()
00246 {
00247 ASSERT (m_pTorrent != NULL);
00248 char sz [100000] = "";
00249 m_pTorrent->get_TorrentComment (sz);
00250 vmsUtf8ToAscii (sz);
00251 return sz;
00252 }
00253
00254 fsString vmsBtDownloadManager::get_FileName(int nIndex)
00255 {
00256 ASSERT (m_pTorrent != NULL);
00257 char sz [MY_MAX_PATH] = "";
00258 m_pTorrent->get_FileName (nIndex, sz);
00259 vmsUtf8ToAscii (sz);
00260 LPSTR psz = sz;
00261 while (*psz)
00262 {
00263 if (*psz == '/')
00264 *psz = '\\';
00265 psz++;
00266 }
00267 return sz;
00268 }
00269
00270 UINT64 vmsBtDownloadManager::get_FileSize(int nIndex)
00271 {
00272 ASSERT (m_pTorrent != NULL);
00273 return m_pTorrent->get_FileSize (nIndex);
00274 }
00275
00276 int vmsBtDownloadManager::get_FilePercentDone(int nIndex)
00277 {
00278 fsTicksMgr time; time.Now ();
00279
00280 if (time - m_info.timeLastDataStatAccess > 1000 || m_info.pfProgress == NULL)
00281 {
00282 if (get_State () != BTDSE_CHECKING_FILES &&
00283 get_State () != BTDSE_QUEUED)
00284 SaveBtDownloadState_FileProgress ();
00285 }
00286
00287 return m_info.pfProgress ? (int) (m_info.pfProgress [nIndex] * 100) : 0;
00288 }
00289
00290 int vmsBtDownloadManager::get_PieceCount()
00291 {
00292 ASSERT (m_pTorrent != NULL);
00293 return m_pTorrent->get_PieceCount ();
00294 }
00295
00296 int vmsBtDownloadManager::get_PieceSize()
00297 {
00298 ASSERT (m_pTorrent != NULL);
00299 return m_pTorrent->get_PieceSize ();
00300 }
00301
00302 fsString vmsBtDownloadManager::get_CurrentTracker()
00303 {
00304 InterlockedIncrement (&m_nUsingBtDownload);
00305 if (m_pDownload == NULL)
00306 {
00307 InterlockedDecrement (&m_nUsingBtDownload);
00308 return m_info.strCurrentTracker;
00309 }
00310 char sz [100000] = "";
00311 m_pDownload->get_CurrentTracker (sz);
00312 InterlockedDecrement (&m_nUsingBtDownload);
00313 return sz;
00314 }
00315
00316 UINT64 vmsBtDownloadManager::get_TotalUploadedByteCount()
00317 {
00318 InterlockedIncrement (&m_nUsingBtDownload);
00319 UINT64 u = IsDownloadStatCanBeRead () ? m_pDownload->get_TotalUploadedByteCount () : m_info.nUploadedBytes;
00320 InterlockedDecrement (&m_nUsingBtDownload);
00321 return u;
00322 }
00323
00324 double vmsBtDownloadManager::get_ShareRating()
00325 {
00326 InterlockedIncrement (&m_nUsingBtDownload);
00327 double d = IsDownloadStatCanBeRead () ? m_pDownload->get_ShareRating () : m_info.fShareRating;
00328 InterlockedDecrement (&m_nUsingBtDownload);
00329 return d;
00330 }
00331
00332 UINT64 vmsBtDownloadManager::get_WastedByteCount()
00333 {
00334 InterlockedIncrement (&m_nUsingBtDownload);
00335 UINT64 u = IsDownloadStatCanBeRead () ? m_pDownload->get_WastedByteCount () : m_info.nWastedBytes;
00336 InterlockedDecrement (&m_nUsingBtDownload);
00337 return u;
00338 }
00339
00340 void vmsBtDownloadManager::get_PeersStat(int *pnPeersConnected, int *pnSeedsTotal, int *pnLeechersTotal, int *pnSeedsConnected)
00341 {
00342 InterlockedIncrement (&m_nUsingBtDownload);
00343
00344 if (m_pDownload)
00345 {
00346 m_pDownload->get_PeersStat(pnPeersConnected, pnSeedsTotal, pnLeechersTotal, pnSeedsConnected);
00347 }
00348 else
00349 {
00350 if (pnPeersConnected)
00351 *pnPeersConnected = 0;
00352 if (pnSeedsTotal)
00353 *pnSeedsTotal = 0;
00354 if (pnLeechersTotal)
00355 *pnLeechersTotal = 0;
00356 if (pnSeedsConnected)
00357 *pnSeedsConnected = 0;
00358 }
00359
00360 InterlockedDecrement (&m_nUsingBtDownload);
00361 }
00362
00363 vmsBtDownloadPeerInfoList* vmsBtDownloadManager::get_PeerInfoList()
00364 {
00365 InterlockedIncrement (&m_nUsingBtDownload);
00366 vmsBtDownloadPeerInfoList *p = m_pDownload ? m_pDownload->get_PeerInfoList () : NULL;
00367 InterlockedDecrement (&m_nUsingBtDownload);
00368 return p;
00369 }
00370
00371 int vmsBtDownloadManager::get_NextAnnounceInterval()
00372 {
00373 InterlockedIncrement (&m_nUsingBtDownload);
00374 BOOL b = m_pDownload ? m_pDownload->get_NextAnnounceInterval () : -1;
00375 InterlockedDecrement (&m_nUsingBtDownload);
00376 return b;
00377 }
00378
00379 vmsBtDownload* vmsBtDownloadManager::get_BtDownload()
00380 {
00381 return m_pDownload;
00382 }
00383
00384 fsString vmsBtDownloadManager::get_OutputFilePathName()
00385 {
00386 ASSERT (m_pTorrent != NULL);
00387 if (m_pTorrent->get_FileCount () == 1)
00388 return get_OutputFilePathName (0);
00389 else
00390 return get_OutputPath ();
00391 }
00392
00393 float vmsBtDownloadManager::GetPercentDone()
00394 {
00395 InterlockedIncrement (&m_nUsingBtDownload);
00396 float f = IsDownloadStatCanBeRead () ? m_pDownload->get_PercentDone () : m_info.fPercentDone;
00397 InterlockedDecrement (&m_nUsingBtDownload);
00398 return f;
00399 }
00400
00401 BOOL vmsBtDownloadManager::IsDone()
00402 {
00403 if (IsDownloadStatCanBeRead () == FALSE)
00404 return m_info.bDone;
00405
00406 vmsBtDownloadStateEx enState = get_State ();
00407
00408 if (enState == BTDSE_SEEDING)
00409 return TRUE;
00410
00411 if (enState != BTDSE_DOWNLOADING)
00412 return GetPercentDone () == 100.0f;
00413
00414 return FALSE;
00415 }
00416
00417 BOOL vmsBtDownloadManager::IsRunning()
00418 {
00419 return m_bThreadDoJob || IsBtDownloadRunning ();
00420 }
00421
00422 int vmsBtDownloadManager::GetNumberOfSections()
00423 {
00424 InterlockedIncrement (&m_nUsingBtDownload);
00425 int i = IsDownloadStatCanBeRead () ? m_pDownload->get_PiecesProgressMap (NULL, NULL) :
00426 (int)m_info.vPieces.size ();
00427 InterlockedDecrement (&m_nUsingBtDownload);
00428 return i;
00429 }
00430
00431 UINT64 vmsBtDownloadManager::GetTotalFilesSize()
00432 {
00433 ASSERT (m_pTorrent != NULL);
00434 return m_pTorrent->get_TotalFilesSize ();
00435 }
00436
00437 UINT64 vmsBtDownloadManager::GetDownloadedBytesCount()
00438 {
00439 InterlockedIncrement (&m_nUsingBtDownload);
00440 UINT64 u = IsDownloadStatCanBeRead () ? m_pDownload->get_TotalDownloadedBytesCount () : m_info.nDownloadedBytes;
00441 InterlockedDecrement (&m_nUsingBtDownload);
00442 return u;
00443 }
00444
00445 BOOL vmsBtDownloadManager::IsDownloading()
00446 {
00447 InterlockedIncrement (&m_nUsingBtDownload);
00448 if (m_pDownload == NULL)
00449 {
00450 InterlockedDecrement (&m_nUsingBtDownload);
00451 return FALSE;
00452 }
00453 BOOL b = get_State () == BTDSE_DOWNLOADING &&
00454 m_pDownload->IsPaused () == FALSE;
00455 InterlockedDecrement (&m_nUsingBtDownload);
00456 return b;
00457 }
00458
00459 void vmsBtDownloadManager::GetSectionInfo(int nIndex, vmsSectionInfo *sect)
00460 {
00461 InterlockedIncrement (&m_nUsingBtDownload);
00462
00463 UINT64 uTotal = GetTotalFilesSize ();
00464 int ns = GetNumberOfSections ();
00465 UINT64 uPerPiece = uTotal / ns;
00466
00467 sect->uDStart = nIndex * uPerPiece;
00468 sect->uDEnd = nIndex == ns-1 ? uTotal : sect->uDStart + uPerPiece - 1;
00469 bool bPC = IsDownloadStatCanBeRead () ? m_pDownload->is_PieceCompleted (nIndex) : m_info.vPieces [nIndex];
00470 sect->uDCurrent = bPC ? sect->uDEnd : sect->uDStart;
00471
00472 InterlockedDecrement (&m_nUsingBtDownload);
00473 }
00474
00475 int vmsBtDownloadManager::GetDownloadingSectionCount()
00476 {
00477 InterlockedIncrement (&m_nUsingBtDownload);
00478 int i = m_pDownload ? m_pDownload->get_DownloadConnectionCount () : 0;
00479 InterlockedDecrement (&m_nUsingBtDownload);
00480 return i;
00481 }
00482
00483 UINT vmsBtDownloadManager::GetSpeed()
00484 {
00485 InterlockedIncrement (&m_nUsingBtDownload);
00486 UINT u = m_pDownload ? m_pDownload->GetDownloadSpeed () : 0;
00487 InterlockedDecrement (&m_nUsingBtDownload);
00488 return u;
00489 }
00490
00491 BOOL vmsBtDownloadManager::MoveToFolder(LPCSTR pszPath)
00492 {
00493 InterlockedIncrement (&m_nUsingBtDownload);
00494
00495 if (m_pDownload == NULL)
00496 {
00497 InterlockedDecrement (&m_nUsingBtDownload);
00498
00499 USES_CONVERSION;
00500
00501
00502 std::wstring wstrSrcPath = A2W (m_info.strOutputPath);
00503 if (wstrSrcPath [wstrSrcPath.length () - 1] != '\\')
00504 wstrSrcPath += '\\';
00505
00506 std::wstring wstrDstPath = A2W (pszPath);
00507 if (wstrDstPath [wstrDstPath.length () - 1] != '\\')
00508 wstrDstPath += '\\';
00509
00510
00511 for (int i = 0; i < get_FileCount (); i++)
00512 {
00513 std::wstring wstrSrc = wstrSrcPath; wstrSrc += get_FileNameW (i);
00514 std::wstring wstrDst = wstrDstPath; wstrDst += get_FileNameW (i);
00515 fsBuildPathToFileW (wstrDst.c_str ());
00516 if (FALSE == MoveFileW (wstrSrc.c_str (), wstrDst.c_str ()) &&
00517 GetFileAttributesW (wstrSrc.c_str ()) != DWORD (-1))
00518 break;
00519 }
00520
00521 if (i != get_FileCount ())
00522 {
00523
00524 while (--i >= 0)
00525 {
00526 std::wstring wstrSrc = wstrSrcPath; wstrSrc += get_FileNameW (i);
00527 std::wstring wstrDst = wstrDstPath; wstrDst += get_FileNameW (i);
00528 MoveFileW (wstrDst.c_str (), wstrSrc.c_str ());
00529 }
00530
00531 return FALSE;
00532 }
00533
00534 RemoveBtDownloadDirectory ();
00535
00536
00537 m_info.strOutputPath = W2A (wstrDstPath.c_str ());
00538
00539 return TRUE;
00540 }
00541
00542 CString str = pszPath;
00543 if (str [str.GetLength () - 1] != '\\')
00544 str += '\\';
00545 ProcessFilePathMacroses (str);
00546 if (FALSE == m_pDownload->MoveToFolder (str))
00547 {
00548 InterlockedDecrement (&m_nUsingBtDownload);
00549 return FALSE;
00550 }
00551
00552 RemoveBtDownloadDirectory ();
00553
00554 m_info.strOutputPath = str;
00555
00556 InterlockedDecrement (&m_nUsingBtDownload);
00557
00558 return TRUE;
00559 }
00560
00561 BOOL vmsBtDownloadManager::IsCantStart()
00562 {
00563 if (m_pDownload == NULL)
00564 return FALSE;
00565
00566 return IsBtDownloadRunning () && get_State () != BTDSE_DOWNLOADING;
00567 }
00568
00569 BOOL vmsBtDownloadManager::IsBtDownloadRunning()
00570 {
00571 InterlockedIncrement (&m_nUsingBtDownload);
00572
00573 if (m_pDownload == NULL)
00574 {
00575 InterlockedDecrement (&m_nUsingBtDownload);
00576 return FALSE;
00577 }
00578
00579 vmsBtDownloadState enState = m_pDownload->GetState ();
00580 BOOL b = enState != BTDSE_SEEDING && enState != BTDSE_QUEUED &&
00581 m_pDownload->IsPaused () == FALSE;
00582
00583 InterlockedDecrement (&m_nUsingBtDownload);
00584
00585 return b;
00586 }
00587
00588 fsInternetResult vmsBtDownloadManager::RestartDownloading()
00589 {
00590 fsInternetResult ir = SetToRestartState ();
00591
00592 if (ir != IR_SUCCESS)
00593 return ir;
00594
00595 return StartDownloading ();
00596 }
00597
00598 fsInternetResult vmsBtDownloadManager::SetToRestartState()
00599 {
00600 m_info.bDone = FALSE;
00601
00602 if (FALSE == DeleteFile ())
00603 return IR_ERROR;
00604
00605 return IR_SUCCESS;
00606 }
00607
00608 BOOL vmsBtDownloadManager::DeleteFile()
00609 {
00610 if (m_pDownload)
00611 {
00612 SaveBtDownloadState ();
00613 DeleteBtDownload ();
00614 }
00615
00616 USES_CONVERSION;
00617
00618 std::wstring wstrSrcPath = A2W (m_info.strOutputPath);
00619 if (wstrSrcPath [wstrSrcPath.length () - 1] != '\\')
00620 wstrSrcPath += '\\';
00621
00622 bool bAllDeletedOk = true;
00623
00624 for (int i = 0; i < get_FileCount (); i++)
00625 {
00626 std::wstring wstr = wstrSrcPath; wstr += get_FileNameW (i);
00627 if (FALSE == ::DeleteFileW (wstr.c_str ()) && GetFileAttributesW (wstr.c_str ()) != DWORD (-1))
00628 bAllDeletedOk = false;
00629 }
00630
00631 RemoveBtDownloadDirectory ();
00632
00633 return bAllDeletedOk;
00634 }
00635
00636 fsInternetResult vmsBtDownloadManager::StartDownloading()
00637 {
00638 if (m_info.bDone || m_bThreadRunning)
00639 return IR_S_FALSE;
00640
00641 if (m_pDownload == NULL && FALSE == CreateBtDownload ())
00642 return IR_ERROR;
00643
00644 if (m_bThreadRunning == false)
00645 {
00646 m_bThreadRunning = m_bThreadDoJob = true;
00647 m_bThreadNeedStop = false;
00648 DWORD dw;
00649 CloseHandle (
00650 CreateThread (NULL, 0, _threadBtDownloadManager, this, 0, &dw));
00651 }
00652
00653 return IR_SUCCESS;
00654 }
00655
00656 void vmsBtDownloadManager::StopDownloading()
00657 {
00658 if (m_pDownload)
00659 m_bThreadNeedStop = true;
00660 }
00661
00662 void vmsBtDownloadManager::LimitTraffic(UINT uLimit)
00663 {
00664 InterlockedIncrement (&m_nUsingBtDownload);
00665 if (m_pDownload)
00666 m_pDownload->SetDownloadLimit ((int)uLimit);
00667 InterlockedDecrement (&m_nUsingBtDownload);
00668 }
00669
00670 UINT vmsBtDownloadManager::GetTrafficLimit()
00671 {
00672 InterlockedIncrement (&m_nUsingBtDownload);
00673 UINT u = m_pDownload ? (UINT)m_pDownload->GetDownloadLimit () : UINT_MAX;
00674 InterlockedDecrement (&m_nUsingBtDownload);
00675 return u;
00676 }
00677
00678 void vmsBtDownloadManager::UseDetailedLog(BOOL bUse)
00679 {
00680
00681 }
00682
00683 int vmsBtDownloadManager::get_ConnectionCount()
00684 {
00685 InterlockedIncrement (&m_nUsingBtDownload);
00686 int i = m_pDownload ? m_pDownload->get_ConnectionCount () : 0;
00687 InterlockedDecrement (&m_nUsingBtDownload);
00688 return i;
00689 }
00690
00691 BOOL vmsBtDownloadManager::SaveState(LPBYTE pb, LPDWORD pdwSize)
00692 {
00693 if (m_pDownload && pb == NULL)
00694 SaveBtDownloadState ();
00695
00696 #define CHECK_SIZE(need) {if (pb != NULL && *pdwSize < (UINT)(pb + need - pbOld)) goto _lSizeErr;}
00697
00698 LPBYTE pbOld = pb;
00699
00700 DWORD dwNeedSize = sizeof (DWORD);
00701
00702 dwNeedSize += sizeof (int) + m_info.strOutputPath.GetLength ();
00703 dwNeedSize += sizeof (int) + m_info.strTorrentUrl.GetLength ();
00704 dwNeedSize += sizeof (int) + m_info.strTrackerUser.GetLength ();
00705 dwNeedSize += sizeof (int) + m_info.strTrackerPassword.GetLength ();
00706
00707 dwNeedSize += sizeof (float) * get_FileCount ();
00708 dwNeedSize += sizeof (int) + m_info.strCurrentTracker.GetLength ();
00709 dwNeedSize += sizeof (m_info.nUploadedBytes);
00710 dwNeedSize += sizeof (m_info.fShareRating);
00711 dwNeedSize += sizeof (m_info.nWastedBytes);
00712 dwNeedSize += sizeof (m_info.fPercentDone);
00713 dwNeedSize += sizeof (m_info.bDone);
00714 dwNeedSize += sizeof (int) + sizeof (BYTE) * m_info.vPieces.size ();
00715 dwNeedSize += sizeof (m_info.nDownloadedBytes);
00716
00717 dwNeedSize += sizeof (m_uLowSpeedMaxTime) + sizeof (m_uTrafficLimit);
00718
00719 if (pb == NULL)
00720 {
00721 DWORD dw;
00722 if (FALSE == m_pTorrent->get_TorrentBuffer (NULL, 0, &dw))
00723 return FALSE;
00724 *pdwSize = dw + sizeof (DWORD);
00725 *pdwSize += m_info.dwFastResumeDataSize + sizeof (DWORD);
00726 *pdwSize += dwNeedSize;
00727 return TRUE;
00728 }
00729
00730 int i;
00731
00732 i = m_info.strTorrentUrl.GetLength ();
00733 CHECK_SIZE (sizeof (int));
00734 CopyMemory (pb, &i, sizeof (int));
00735 pb += sizeof (int);
00736 CHECK_SIZE (i);
00737 CopyMemory (pb, m_info.strTorrentUrl, i);
00738 pb += i;
00739
00740 i = m_info.strOutputPath.GetLength ();
00741 CHECK_SIZE (sizeof (int));
00742 CopyMemory (pb, &i, sizeof (int));
00743 pb += sizeof (int);
00744 CHECK_SIZE (i);
00745 CopyMemory (pb, m_info.strOutputPath, i);
00746 pb += i;
00747
00748 i = m_info.strTrackerUser.GetLength ();
00749 CHECK_SIZE (sizeof (int));
00750 CopyMemory (pb, &i, sizeof (int));
00751 pb += sizeof (int);
00752 CHECK_SIZE (i);
00753 CopyMemory (pb, m_info.strTrackerUser, i);
00754 pb += i;
00755
00756 i = m_info.strTrackerPassword.GetLength ();
00757 CHECK_SIZE (sizeof (int));
00758 CopyMemory (pb, &i, sizeof (int));
00759 pb += sizeof (int);
00760 CHECK_SIZE (i);
00761 CopyMemory (pb, m_info.strTrackerPassword, i);
00762 pb += i;
00763
00764 CHECK_SIZE (sizeof (DWORD));
00765 DWORD dw; dw = *pdwSize - (pb - pbOld - sizeof (DWORD));
00766 if (FALSE == m_pTorrent->get_TorrentBuffer (pb + sizeof (DWORD), dw, &dw))
00767 goto _lSizeErr;
00768 *((LPDWORD)pb) = dw;
00769 pb += sizeof (DWORD) + dw;
00770
00771 CHECK_SIZE (sizeof (DWORD));
00772 *((LPDWORD)pb) = m_info.dwFastResumeDataSize;
00773 pb += sizeof (DWORD);
00774 if (m_info.dwFastResumeDataSize != 0)
00775 {
00776 CHECK_SIZE (m_info.dwFastResumeDataSize);
00777 CopyMemory (pb, m_info.pbFastResumeData, m_info.dwFastResumeDataSize);
00778 pb += m_info.dwFastResumeDataSize;
00779 }
00780
00781 CHECK_SIZE (get_FileCount () * sizeof (float));
00782 CopyMemory (pb, m_info.pfProgress, get_FileCount () * sizeof (float));
00783 pb += get_FileCount () * sizeof (float);
00784
00785 i = m_info.strCurrentTracker.GetLength ();
00786 CHECK_SIZE (sizeof (int));
00787 CopyMemory (pb, &i, sizeof (int));
00788 pb += sizeof (int);
00789 CHECK_SIZE (i);
00790 CopyMemory (pb, m_info.strCurrentTracker, i);
00791 pb += i;
00792
00793 CHECK_SIZE (sizeof (m_info.nUploadedBytes));
00794 CopyMemory (pb, &m_info.nUploadedBytes, sizeof (m_info.nUploadedBytes));
00795 pb += sizeof (m_info.nUploadedBytes);
00796
00797 CHECK_SIZE (sizeof (m_info.fShareRating));
00798 CopyMemory (pb, &m_info.fShareRating, sizeof (m_info.fShareRating));
00799 pb += sizeof (m_info.fShareRating);
00800
00801 CHECK_SIZE (sizeof (m_info.nWastedBytes));
00802 CopyMemory (pb, &m_info.nWastedBytes, sizeof (m_info.nWastedBytes));
00803 pb += sizeof (m_info.nWastedBytes);
00804
00805 CHECK_SIZE (sizeof (m_info.fPercentDone));
00806 CopyMemory (pb, &m_info.fPercentDone, sizeof (m_info.fPercentDone));
00807 pb += sizeof (m_info.fPercentDone);
00808
00809 CHECK_SIZE (sizeof (m_info.bDone));
00810 CopyMemory (pb, &m_info.bDone, sizeof (m_info.bDone));
00811 pb += sizeof (m_info.bDone);
00812
00813 i = m_info.vPieces.size ();
00814 CHECK_SIZE (sizeof (int));
00815 CopyMemory (pb, &i, sizeof (int));
00816 pb += sizeof (int);
00817 CHECK_SIZE (i);
00818 int j;
00819 for (j = 0; j < i; j++)
00820 *pb++ = m_info.vPieces [j];
00821
00822 CHECK_SIZE (sizeof (m_info.nDownloadedBytes));
00823 CopyMemory (pb, &m_info.nDownloadedBytes, sizeof (m_info.nDownloadedBytes));
00824 pb += sizeof (m_info.nDownloadedBytes);
00825
00826 CHECK_SIZE (sizeof (m_info.dwFlags));
00827 *((LPDWORD)pb) = m_info.dwFlags;
00828 pb += sizeof (m_info.dwFlags);
00829
00830 CHECK_SIZE (sizeof (m_uLowSpeedMaxTime));
00831 *((LPDWORD)pb) = m_uLowSpeedMaxTime;
00832 pb += sizeof (m_uLowSpeedMaxTime);
00833
00834 CHECK_SIZE (sizeof (m_uTrafficLimit));
00835 *((LPDWORD)pb) = m_uTrafficLimit;
00836 pb += sizeof (m_uTrafficLimit);
00837
00838 *pdwSize = pb - pbOld;
00839
00840 return TRUE;
00841
00842 _lSizeErr:
00843 SaveState (NULL, pdwSize);
00844 return FALSE;
00845 }
00846
00847 BOOL vmsBtDownloadManager::LoadState(LPBYTE lpBuffer, LPDWORD pdwSize, WORD wVer)
00848 {
00849 ASSERT (wVer >= 10);
00850
00851 LPBYTE pbStart = lpBuffer;
00852
00853 int i;
00854 char sz [10000];
00855
00856 if (wVer > 10)
00857 {
00858 CopyMemory (&i, lpBuffer, sizeof (int));
00859 lpBuffer += sizeof (int);
00860 CopyMemory (sz, lpBuffer, i);
00861 sz [i] = 0;
00862 lpBuffer += i;
00863 m_info.strTorrentUrl = sz;
00864 }
00865 else
00866 {
00867 m_info.strTorrentUrl = "";
00868 }
00869
00870 CopyMemory (&i, lpBuffer, sizeof (int));
00871 lpBuffer += sizeof (int);
00872 CopyMemory (sz, lpBuffer, i);
00873 sz [i] = 0;
00874 m_info.strOutputPath = sz;
00875 lpBuffer += i;
00876
00877 CopyMemory (&i, lpBuffer, sizeof (int));
00878 lpBuffer += sizeof (int);
00879 CopyMemory (sz, lpBuffer, i);
00880 sz [i] = 0;
00881 lpBuffer += i;
00882 m_info.strTrackerUser = sz;
00883
00884 CopyMemory (&i, lpBuffer, sizeof (int));
00885 lpBuffer += sizeof (int);
00886 CopyMemory (sz, lpBuffer, i);
00887 sz [i] = 0;
00888 lpBuffer += i;
00889 m_info.strTrackerPassword = sz;
00890
00891 DWORD dwTorrentSize = *((LPDWORD)lpBuffer);
00892 LPBYTE pbTorrent = lpBuffer + sizeof (DWORD);
00893 lpBuffer += sizeof (DWORD) + dwTorrentSize;
00894
00895 m_pTorrent = _BT.CreateTorrentFileObject ();
00896 if (m_pTorrent == NULL)
00897 return FALSE;
00898 if (FALSE == m_pTorrent->LoadFromBuffer (pbTorrent, dwTorrentSize))
00899 return FALSE;
00900
00901 m_info.dwFastResumeDataSize = *((LPDWORD)lpBuffer);
00902 lpBuffer += sizeof (DWORD);
00903 SAFE_DELETE_ARRAY (m_info.pbFastResumeData);
00904 if (m_info.dwFastResumeDataSize)
00905 {
00906 m_info.pbFastResumeData = new BYTE [m_info.dwFastResumeDataSize];
00907 CopyMemory (m_info.pbFastResumeData, lpBuffer, m_info.dwFastResumeDataSize);
00908 lpBuffer += m_info.dwFastResumeDataSize;
00909 }
00910
00911 if (wVer > 11)
00912 {
00913 m_info.pfProgress = new float [get_FileCount () * sizeof (float)];
00914 CopyMemory (m_info.pfProgress, lpBuffer, get_FileCount () * sizeof (float));
00915 lpBuffer += get_FileCount () * sizeof (float);
00916
00917 CopyMemory (&i, lpBuffer, sizeof (int));
00918 lpBuffer += sizeof (int);
00919 CopyMemory (sz, lpBuffer, i);
00920 sz [i] = 0;
00921 lpBuffer += i;
00922 m_info.strCurrentTracker = sz;
00923
00924 CopyMemory (&m_info.nUploadedBytes, lpBuffer, sizeof (m_info.nUploadedBytes));
00925 lpBuffer += sizeof (m_info.nUploadedBytes);
00926
00927 CopyMemory (&m_info.fShareRating, lpBuffer, sizeof (m_info.fShareRating));
00928 lpBuffer += sizeof (m_info.fShareRating);
00929
00930 CopyMemory (&m_info.nWastedBytes, lpBuffer, sizeof (m_info.nWastedBytes));
00931 lpBuffer += sizeof (m_info.nWastedBytes);
00932
00933 CopyMemory (&m_info.fPercentDone, lpBuffer, sizeof (m_info.fPercentDone));
00934 lpBuffer += sizeof (m_info.fPercentDone);
00935
00936 CopyMemory (&m_info.bDone, lpBuffer, sizeof (m_info.bDone));
00937 lpBuffer += sizeof (m_info.bDone);
00938
00939 CopyMemory (&i, lpBuffer, sizeof (int));
00940 lpBuffer += sizeof (int);
00941 m_info.vPieces.clear ();
00942 while (i--)
00943 m_info.vPieces.push_back ((*lpBuffer++) != 0);
00944
00945 CopyMemory (&m_info.nDownloadedBytes, lpBuffer, sizeof (m_info.nDownloadedBytes));
00946 lpBuffer += sizeof (m_info.nDownloadedBytes);
00947 }
00948 else
00949 {
00950 PostCreateTorrentObject ();
00951 }
00952
00953 m_info.dwFlags = *((LPDWORD)lpBuffer);
00954 lpBuffer += sizeof (DWORD);
00955
00956 m_uLowSpeedMaxTime = *((LPUINT)lpBuffer);
00957 lpBuffer += sizeof (UINT);
00958
00959 m_uTrafficLimit = *((LPUINT)lpBuffer);
00960 lpBuffer += sizeof (UINT);
00961
00962 *pdwSize = lpBuffer - pbStart;
00963
00964 if ((m_info.dwFlags & BTDF_DISABLE_SEEDING) == 0 && m_info.bDone)
00965 EnableSeeding (TRUE);
00966
00967 return TRUE;
00968 }
00969
00970 BOOL vmsBtDownloadManager::IsStoppedByUser()
00971 {
00972 return m_bStoppedByUser;
00973 }
00974
00975 DWORD WINAPI vmsBtDownloadManager::_threadBtDownloadManager(LPVOID lp)
00976 {
00977 #define LOG_local(x) LOG("vmsBTDM::_tBTDM(" << (DWORD)lp << "): " << x << nl)
00978
00979 vmsBtDownloadManager *pthis = (vmsBtDownloadManager*)lp;
00980 vmsBtDownloadStateEx enPrevState = BTDSE_QUEUED;
00981
00982 pthis->RaiseEvent (BTDME_DOWNLOAD_STARTED);
00983
00984 LOG_local ("start");
00985
00986 while (pthis->get_State () == BTDSE_QUEUED && pthis->m_bThreadNeedStop == false)
00987 Sleep (100);
00988
00989 LOG_local ("1");
00990
00991 bool bDownloading = false;
00992 bool bMayFilesEvent = true;
00993 fsTicksMgr time0Speed;
00994
00995 while (pthis->IsBtDownloadRunning () && pthis->m_bThreadNeedStop == false)
00996 {
00997
00998 {
00999 vmsBtDownloadStateEx enCurrState = pthis->get_State ();
01000 if (enCurrState != enPrevState)
01001 {
01002 switch (enCurrState)
01003 {
01004 case BTDSE_CHECKING_FILES:
01005 if (bMayFilesEvent)
01006 pthis->RaiseEvent (BTDME_CHECKING_FILES);
01007 bMayFilesEvent = false;
01008 break;
01009
01010 case BTDSE_ALLOCATING:
01011 if (bMayFilesEvent)
01012 pthis->RaiseEvent (BTDME_ALLOCATING);
01013 bMayFilesEvent = false;
01014 break;
01015
01016 case BTDSE_DOWNLOADING:
01017 _DldsMgr.ProcessDownloads ();
01018 break;
01019 }
01020
01021 enPrevState = enCurrState;
01022 }
01023 }
01024
01025 Sleep (100);
01026 if (bDownloading == false)
01027 {
01028 if (pthis->GetSpeed ())
01029 {
01030 bDownloading = true;
01031 pthis->RaiseEvent (BTDME_DOWNLOADING);
01032 }
01033 }
01034 else
01035 {
01036 if (pthis->GetSpeed () == 0)
01037 {
01038 fsTicksMgr now;
01039
01040 if (now - time0Speed > 120 * 1000)
01041 {
01042
01043 pthis->m_pDownload->Pause ();
01044 pthis->SaveBtDownloadState ();
01045 pthis->DeleteBtDownload ();
01046 pthis->CreateBtDownload ();
01047
01048 time0Speed.Now ();
01049 bDownloading = false;
01050 enPrevState = BTDSE_QUEUED;
01051 while (pthis->get_State () == BTDSE_QUEUED && pthis->m_bThreadNeedStop == false)
01052 Sleep (100);
01053 }
01054 }
01055 else
01056 {
01057 time0Speed.Now ();
01058 }
01059 }
01060 }
01061
01062 LOG_local ("2");
01063
01064 if (pthis->m_pDownload != NULL &&
01065 (pthis->m_bThreadNeedStop || pthis->get_State () != BTDSE_SEEDING ||
01066 (pthis->m_info.dwFlags & BTDF_DISABLE_SEEDING) != 0 ||
01067 _DldsMgr.AllowStartNewDownloads () == FALSE))
01068 {
01069 LOG_local ("need delete bt download");
01070 pthis->m_pDownload->Pause ();
01071 LOG_local ("saving state");
01072 pthis->SaveBtDownloadState ();
01073 LOG_local ("deleting");
01074 pthis->DeleteBtDownload ();
01075 }
01076 else
01077 {
01078 #ifdef _USELOGGING
01079 if (pthis->m_pDownload != NULL)
01080 LOG_local ("download was not deleted for some reason");
01081 #endif
01082 }
01083
01084 LOG_local ("3");
01085
01086 pthis->m_bThreadDoJob = false;
01087
01088 try{pthis->RaiseEvent (BTDME_DOWNLOAD_STOPPED_OR_DONE);}catch(...){}
01089
01090 LOG_local ("4");
01091
01092 if (pthis->get_State () == BTDSE_SEEDING)
01093 pthis->RaiseEvent (BTDME_SEEDING);
01094
01095 LOG_local ("done");
01096
01097 pthis->m_bThreadRunning = false;
01098
01099 return 0;
01100 }
01101
01102 void vmsBtDownloadManager::StopThread()
01103 {
01104 if (m_bThreadRunning)
01105 {
01106 StopDownloading ();
01107 while (m_bThreadRunning)
01108 Sleep (10);
01109 }
01110 }
01111
01112 void vmsBtDownloadManager::SaveBtDownloadState()
01113 {
01114 InterlockedIncrement (&m_nUsingBtDownload);
01115
01116 if (m_pDownload == NULL || m_pDownload->is_HandleValid () == FALSE ||
01117 get_State () == BTDSE_QUEUED)
01118 {
01119 InterlockedDecrement (&m_nUsingBtDownload);
01120 return;
01121 }
01122
01123 SaveBtDownloadState_FileProgress ();
01124 m_info.strCurrentTracker = get_CurrentTracker ();
01125 m_info.nUploadedBytes = get_TotalUploadedByteCount ();
01126 m_info.fShareRating = get_ShareRating ();
01127 m_info.nWastedBytes = get_WastedByteCount ();
01128 m_info.fPercentDone = GetPercentDone ();
01129 m_info.bDone = IsDone ();
01130
01131 SaveBtDownloadState_Pieces ();
01132
01133 m_info.nDownloadedBytes = GetDownloadedBytesCount ();
01134
01135 SAFE_DELETE_ARRAY (m_info.pbFastResumeData);
01136 m_info.dwFastResumeDataSize = 0;
01137 if (m_pDownload->get_FastResumeData (NULL, 0, &m_info.dwFastResumeDataSize) &&
01138 m_info.dwFastResumeDataSize != 0)
01139 {
01140 m_info.pbFastResumeData = new BYTE [m_info.dwFastResumeDataSize];
01141 if (FALSE == m_pDownload->get_FastResumeData (m_info.pbFastResumeData, m_info.dwFastResumeDataSize, &m_info.dwFastResumeDataSize))
01142 {
01143 SAFE_DELETE_ARRAY (m_info.pbFastResumeData);
01144 m_info.dwFastResumeDataSize = 0;
01145 }
01146 }
01147
01148 InterlockedDecrement (&m_nUsingBtDownload);
01149 }
01150
01151 void vmsBtDownloadManager::SaveBtDownloadState_FileProgress()
01152 {
01153 if (m_info.pfProgress == NULL)
01154 {
01155 if (m_pDownload == NULL)
01156 return;
01157 m_info.pfProgress = new float [get_FileCount ()];
01158 }
01159
01160 if (m_pDownload)
01161 {
01162 m_pDownload->get_FileProgress (m_info.pfProgress);
01163 m_info.timeLastDataStatAccess.Now ();
01164 }
01165 }
01166
01167 DWORD vmsBtDownloadManager::RaiseEvent(vmsBtDownloadManagerEvent ev, DWORD dw)
01168 {
01169 if (m_pfnEvHandler == NULL)
01170 return 0;
01171
01172 return m_pfnEvHandler (this, ev, dw, m_lpEvParam);
01173 }
01174
01175 void vmsBtDownloadManager::PostCreateTorrentObject()
01176 {
01177 for (int i = 0; i < get_PieceCount (); i++)
01178 m_info.vPieces.push_back (false);
01179 }
01180
01181 BOOL vmsBtDownloadManager::IsDownloadStatCanBeRead()
01182 {
01183 InterlockedIncrement (&m_nUsingBtDownload);
01184 BOOL b = m_pDownload && get_State () != BTDSE_QUEUED &&
01185 get_State () != BTDSE_CHECKING_FILES;
01186 InterlockedDecrement (&m_nUsingBtDownload);
01187 return b;
01188 }
01189
01190 void vmsBtDownloadManager::EnableSeeding(BOOL bEnable)
01191 {
01192 if (bEnable)
01193 {
01194 disable_Flags (BTDF_DISABLE_SEEDING);
01195 if (m_pDownload == NULL && m_info.bDone)
01196 {
01197 CreateBtDownload ();
01198
01199 m_bThreadRunning = true;
01200 DWORD dw;
01201 CloseHandle (
01202 CreateThread (NULL, 0, _threadCheckStartSeeding, this, 0, &dw));
01203 }
01204 }
01205 else
01206 {
01207 enable_Flags (BTDF_DISABLE_SEEDING);
01208 StopSeeding ();
01209 }
01210 }
01211
01212 void vmsBtDownloadManager::RecursiveRemoveDirectory(LPCWSTR pwszPath)
01213 {
01214 std::wstring wstrPath = pwszPath;
01215 if (wstrPath [wstrPath.length () - 1] != '\\')
01216 wstrPath += '\\';
01217 std::wstring wstrMask = wstrPath; wstrMask += L"*.*";
01218
01219 fs::list <std::wstring> vFolders;
01220
01221 WIN32_FIND_DATAW wfd;
01222 HANDLE hFind = FindFirstFileW (wstrMask.c_str (), &wfd);
01223 if (hFind != INVALID_HANDLE_VALUE)
01224 {
01225 do
01226 {
01227 std::wstring wstr = wstrPath; wstr += wfd.cFileName;
01228 DWORD dw = GetFileAttributesW (wstr.c_str ());
01229 if (dw != DWORD (-1) && (dw & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
01230 wcscmp (wfd.cFileName, L".") && wcscmp (wfd.cFileName, L".."))
01231 {
01232 vFolders.add (wstr);
01233 }
01234 }
01235 while (FindNextFileW (hFind, &wfd));
01236
01237 FindClose (hFind);
01238
01239 for (int i = 0; i < vFolders.size (); i++)
01240 RecursiveRemoveDirectory (vFolders [i].c_str ());
01241
01242 RemoveDirectoryW (pwszPath);
01243 }
01244 }
01245
01246 void vmsBtDownloadManager::RemoveBtDownloadDirectory()
01247 {
01248 USES_CONVERSION;
01249 std::wstring wstr = get_FileNameW (0);
01250 if (wcschr (wstr.c_str (), '\\'))
01251 {
01252 std::wstring wstr2 = A2W (m_info.strOutputPath);
01253 for (int i = 0; wstr [i] != '\\'; i++)
01254 wstr2 += wstr [i];
01255 RecursiveRemoveDirectory (wstr2.c_str ());
01256 }
01257 }
01258
01259 DWORD WINAPI vmsBtDownloadManager::_threadCheckStartSeeding(LPVOID lp)
01260 {
01261 vmsBtDownloadManager *pthis = (vmsBtDownloadManager*)lp;
01262
01263 while (pthis->m_bThreadNeedStop == false && pthis->m_pDownload != NULL)
01264 {
01265 vmsBtDownloadStateEx s = pthis->get_State ();
01266 if (s != BTDSE_QUEUED && s != BTDSE_CHECKING_FILES && s != BTDSE_CONNECTING_TRACKER)
01267 break;
01268 if (s == BTDSE_CONNECTING_TRACKER && pthis->GetPercentDone () != 100.0f)
01269 break;
01270 Sleep (5);
01271 }
01272
01273 if (pthis->get_State () != BTDSE_SEEDING ||
01274 (pthis->m_info.dwFlags & BTDF_DISABLE_SEEDING) != 0)
01275 pthis->DeleteBtDownload ();
01276 else
01277 pthis->RaiseEvent (BTDME_SEEDING);
01278
01279 pthis->m_bThreadRunning = false;
01280
01281 return 0;
01282 }
01283
01284 void vmsBtDownloadManager::StopSeeding()
01285 {
01286 if (get_State () == BTDSE_SEEDING)
01287 {
01288 SaveBtDownloadState ();
01289 DeleteBtDownload ();
01290 }
01291 }
01292
01293 std::wstring vmsBtDownloadManager::get_FileNameW(int nIndex)
01294 {
01295 ASSERT (m_pTorrent != NULL);
01296 char sz [MY_MAX_PATH] = "";
01297 m_pTorrent->get_FileName (nIndex, sz);
01298 std::wstring wstr = vmsUtf8Unicode (sz);
01299 LPWSTR pwsz = (LPWSTR)wstr.c_str ();
01300 while (*pwsz)
01301 {
01302 if (*pwsz == '/')
01303 *pwsz = '\\';
01304 pwsz++;
01305 }
01306 return wstr;
01307 }
01308
01309 int vmsBtDownloadManager::get_CurrentTaskProgress()
01310 {
01311 if (m_pDownload == NULL)
01312 return -1;
01313 return m_pDownload->get_CurrentTaskProgress ();
01314 }
01315
01316 void vmsBtDownloadManager::SaveBtDownloadState_Pieces()
01317 {
01318 m_info.vPieces.clear ();
01319 int ns = GetNumberOfSections ();
01320 for (int i = 0; i < ns; i++)
01321 m_info.vPieces.push_back (m_pDownload->is_PieceCompleted (i));
01322 }
01323
01324 void vmsBtDownloadManager::GetSectionsInfo(std::vector <vmsSectionInfo> &v)
01325 {
01326 InterlockedIncrement (&m_nUsingBtDownload);
01327
01328 v.clear ();
01329
01330 vmsSectionInfo sect;
01331
01332 UINT64 uTotal = GetTotalFilesSize ();
01333 int ns = GetNumberOfSections ();
01334 UINT64 uPerPiece = uTotal / ns;
01335 BOOL bDSCBR = IsDownloadStatCanBeRead ();
01336
01337 for (int i = 0; i < ns; i++)
01338 {
01339 sect.uDStart = i * uPerPiece;
01340 sect.uDEnd = i == ns-1 ? uTotal : sect.uDStart + uPerPiece - 1;
01341 bool bPC = bDSCBR ? m_pDownload->is_PieceCompleted (i) : m_info.vPieces [i];
01342 sect.uDCurrent = bPC ? sect.uDEnd : sect.uDStart;
01343 v.push_back (sect);
01344 }
01345
01346 InterlockedDecrement (&m_nUsingBtDownload);
01347 }
01348
01349 UINT64 vmsBtDownloadManager::get_SplittedByteCountAtBeginningOfFile()
01350 {
01351 InterlockedIncrement (&m_nUsingBtDownload);
01352
01353 UINT64 uTotal = GetTotalFilesSize ();
01354 int ns = GetNumberOfSections ();
01355 UINT64 uPerPiece = uTotal / ns;
01356
01357 UINT64 uRes = 0;
01358 bool bIDSCBR = IsDownloadStatCanBeRead () != 0;
01359
01360 for (int i = 0; i < ns; i++)
01361 {
01362 if (false == (bIDSCBR ? m_pDownload->is_PieceCompleted (i) : m_info.vPieces [i]))
01363 break;
01364
01365 uRes += uPerPiece;
01366 }
01367
01368 InterlockedDecrement (&m_nUsingBtDownload);
01369
01370 return uRes;
01371 }
01372
01373 fsString vmsBtDownloadManager::get_RootFolderName()
01374 {
01375 if (get_FileCount () == 1)
01376 return "";
01377
01378 int nOffset = 0;
01379
01380 for (int i = 0; i < get_FileCount (); i++)
01381 {
01382 fsString str = get_FileName (i);
01383 if (nOffset == 0)
01384 {
01385 LPCSTR psz = strchr (str, '\\');
01386 if (psz)
01387 nOffset = psz - str + 1;
01388 else
01389 break;
01390 }
01391 else
01392 {
01393 LPCSTR psz = strchr (str, '\\');
01394 int nOffset2 = 0;
01395 if (psz)
01396 nOffset2 = psz - str + 1;
01397 if (nOffset2 != nOffset || strnicmp (str, get_FileName (i-1), nOffset))
01398 {
01399 nOffset = 0;
01400 break;
01401 }
01402 }
01403 }
01404
01405 if (nOffset == 0)
01406 return "";
01407
01408 char sz [MY_MAX_PATH];
01409 lstrcpyn (sz, get_FileName (0), nOffset);
01410 return sz;
01411 }