00001
00002
00003
00004
00005
00006 #include "stdafx.h"
00007 #include "fsDownloadMgr.h"
00008 #include "inetutil.h"
00009 #include "misc.h"
00010 #include "Hash\vmsHash.h"
00011
00012 #ifndef FDM_DLDR__RAWCODEONLY
00013 #include "DownloadsWnd.h"
00014 #include "AERDlg.h"
00015 #include "SCRDlg.h"
00016 #include "MyMessageBox.h"
00017 #include "vmsMaliciousDownloadChecker.h"
00018 #endif
00019
00020 #include "fsdownloadsmgr.h"
00021
00022 #ifdef _DEBUG
00023 #undef THIS_FILE
00024 static char THIS_FILE[]=__FILE__;
00025 #define new DEBUG_NEW
00026 #endif
00027
00028 vmsCriticalSection fsDownloadMgr::m_csRenameFile;
00029
00030 fsDownloadMgr::fsDownloadMgr(struct fsDownload* dld)
00031 {
00032 m_iThread = 0;
00033 m_bThreadRunning = FALSE;
00034 m_state = DS_STOPPED;
00035 m_dld = dld;
00036
00037 m_dldr.SetEventFunc (_DownloaderEvents, this);
00038
00039 ZeroMemory (&m_dp, sizeof (m_dp));
00040 m_dp.wStructSize = sizeof (m_dp);
00041 fsDP_BuffersInfo bi;
00042 fsDP_GetDefaults (&m_dp, &bi, TRUE);
00043
00044 ZeroMemory (m_dldr.DNP (), sizeof (fsDownload_NetworkProperties));
00045
00046 m_state = 0;
00047
00048 m_hOutFile = INVALID_HANDLE_VALUE;
00049
00050 m_pfnEvents = NULL;
00051 m_pfnEventDesc = NULL;
00052 m_uNeedStartFrom = 0;
00053 m_dwDownloadFileFlags = DFF_NEED_INIT_FILE;
00054 m_bFatalError = FALSE;
00055
00056 m_bCantStart = FALSE;
00057
00058 m_uMirrRecalcSpeedTime = 60;
00059
00060 m_tikLastMirrMeasureTime.Now ();
00061 m_bNeedStartAgain = FALSE;
00062 m_bRename_CheckIfRenamed = FALSE;
00063
00064 #ifndef FDM_DLDR__RAWCODEONLY
00065 m_mdc = NULL;
00066 #endif
00067
00068 m_bRSsupportDone = false;
00069
00070 m_bDontCreateNewSections = FALSE;
00071 }
00072
00073 fsDownloadMgr::~fsDownloadMgr()
00074 {
00075 StopDownloading ();
00076 MSG msg;
00077 while (m_iThread )
00078 {
00079 while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE))
00080 DispatchMessage (&msg);
00081
00082 Sleep (10);
00083 }
00084
00085 CloseFile ();
00086 SAFE_DELETE_ARRAY (m_dp.pszFileName);
00087 SAFE_DELETE_ARRAY (m_dp.pszAdditionalExt);
00088 SAFE_DELETE_ARRAY (m_dp.pszCreateExt);
00089 fsDNP_GetByUrl_Free (m_dldr.DNP ());
00090 }
00091
00092 fsDownload_NetworkProperties* fsDownloadMgr::GetDNP()
00093 {
00094 return m_dldr.DNP ();
00095 }
00096
00097 fsDownload_Properties* fsDownloadMgr::GetDP()
00098 {
00099 return &m_dp;
00100 }
00101
00102 fsInternetResult fsDownloadMgr::StartDownloading()
00103 {
00104 if (IsRunning () || m_dldr.IsDone () || IsQueringSize ())
00105 return IR_S_FALSE;
00106
00107 m_state = DS_NEEDSTART;
00108
00109 DWORD dwThread;
00110 m_bThreadRunning = TRUE;
00111 InterlockedIncrement (&m_iThread);
00112 CloseHandle (CreateThread (NULL, 0, _threadDownloadMgr, this, 0, &dwThread));
00113
00114 return IR_SUCCESS;
00115 }
00116
00117 fsInternetResult fsDownloadMgr::CreateInternetSession()
00118 {
00119 InternetAutodial (INTERNET_AUTODIAL_FORCE_ONLINE, NULL);
00120 return IR_SUCCESS;
00121 }
00122
00123 void fsDownloadMgr::ApplyProperties()
00124 {
00125 m_dldr.Set_Timeout (m_dp.uTimeout);
00126 m_dldr.SetRetryTime (m_dp.uRetriesTime);
00127 m_dldr.SetMaxReconnectionNumber (m_dp.uMaxAttempts);
00128 m_dldr.SetSectionMinSize (m_dp.uSectionMinSize);
00129 m_dldr.DontRestartIfNoRanges (m_dp.dwFlags & DPF_DONTRESTARTIFNORESUME);
00130
00131
00132 #ifndef FDM_DLDR__RAWCODEONLY
00133 m_dldr.UseZipPreview (_App.NewDL_UseZIPPreview ());
00134 #else
00135 m_dldr.UseZipPreview (FALSE);
00136 #endif
00137
00138 m_dldr.StopOnAccDenied (m_dp.aEP [DFE_ACCDENIED] == DFEP_STOP);
00139 m_dldr.StopOnFileNotFound (m_dp.aEP [DFE_NOTFOUND] == DFEP_STOP);
00140
00141 if (m_dp.bIgnoreRestrictions == FALSE)
00142 m_dldr.LimitTraffic (m_dp.uTrafficRestriction);
00143 else
00144 m_dldr.LimitTraffic (UINT_MAX);
00145
00146 DoRapidshareSupport ();
00147
00148 if (m_state & DS_DOWNLOADING)
00149 m_state |= DS_NEEDADDSECTION;
00150 }
00151
00152 DWORD WINAPI fsDownloadMgr::_threadDownloadMgr(LPVOID lp)
00153 {
00154 fsDownloadMgr *pThis = (fsDownloadMgr*) lp;
00155 BOOL bAddSection = TRUE;
00156
00157 if (fsDownloadMgr::is_GlobalOffline ())
00158 fsDownloadMgr::set_GlobalOffline (FALSE);
00159
00160 pThis->m_bThreadRunning = TRUE;
00161
00162 BOOL bSSR = pThis->Event (DE_EXTERROR, DMEE_STARTING);
00163
00164 #ifndef FDM_DLDR__RAWCODEONLY
00165 if (bSSR)
00166 bSSR = pThis->CheckIfMalicious ();
00167 #endif
00168
00169 if (bSSR == FALSE)
00170 {
00171 pThis->m_bFatalError = TRUE;
00172 pThis->Event (DE_EXTERROR, DMEE_FATALERROR);
00173 }
00174
00175 fsTicksMgr tick0SpeedStart;
00176 tick0SpeedStart.Now ();
00177
00178 if (bSSR) while ((pThis->m_state & DS_DONE) == 0)
00179 {
00180
00181 if (pThis->m_state & DS_NEEDSTART)
00182 {
00183 pThis->m_state &= ~ DS_NEEDSTART;
00184 bAddSection = TRUE;
00185
00186
00187 for (UINT i = 0; i < pThis->m_dp.uMaxAttempts; i++)
00188 {
00189 pThis->m_lastError = pThis->StartDownload ();
00190 tick0SpeedStart.Now ();
00191
00192 if (pThis->m_state & DS_NEEDSTOP ||
00193 pThis->m_lastError == IR_S_FALSE ||
00194 pThis->m_lastError == IR_RANGESNOTAVAIL ||
00195 pThis->m_lastError == IR_DOUBTFUL_RANGESRESPONSE)
00196 break;
00197
00198 if (pThis->m_lastError == IR_SUCCESS)
00199 {
00200 pThis->m_state |= DS_DOWNLOADING;
00201 if (pThis->m_dldr.IsResumeSupported () == RST_NONE)
00202 pThis->Event (LS (L_NORESUME), EDT_WARNING);
00203 break;
00204 }
00205 else
00206 {
00207 pThis->m_bCantStart = TRUE;
00208
00209 if (pThis->m_dp.uRetriesTime && i+1 != pThis->m_dp.uMaxAttempts)
00210 {
00211 CHAR szStr [1000];
00212 sprintf (szStr, LS (L_PAUSESECS), pThis->m_dp.uRetriesTime/1000);
00213 pThis->Event (szStr);
00214 if (pThis->SleepInterval () == FALSE)
00215 break;
00216 }
00217 }
00218 }
00219
00220 pThis->m_bCantStart = FALSE;
00221
00222 if ((pThis->m_state & DS_DOWNLOADING) == 0 && pThis->m_lastError != IR_S_FALSE)
00223 {
00224 if ((pThis->m_state & DS_NEEDSTOP) == 0)
00225 {
00226
00227 pThis->Event (LS (L_DLDSTOPPED), pThis->m_lastError == IR_S_FALSE ? EDT_RESPONSE_S : EDT_RESPONSE_E);
00228 pThis->Event (DE_EXTERROR, DMEE_FATALERROR);
00229 pThis->m_bFatalError = TRUE;
00230 pThis->m_state = 0;
00231 break;
00232 }
00233 }
00234 }
00235
00236 if (pThis->m_state & DS_NEEDSTOP)
00237 {
00238 pThis->StopDownload ();
00239 pThis->m_state = 0;
00240 pThis->Event (LS (L_DLDSTOPPED), EDT_RESPONSE_S);
00241 break;
00242 }
00243
00244 if (pThis->m_state & DS_DOWNLOADING)
00245 {
00246 if (bAddSection)
00247 {
00248 fsTicksMgr curTicks;
00249 curTicks.Now ();
00250
00251
00252 if (curTicks - pThis->m_ticksStart > 1200)
00253 {
00254 bAddSection = FALSE;
00255 pThis->AddSection ();
00256 }
00257 }
00258
00259 if (pThis->m_dldr.GetSpeed () == 0 &&
00260 pThis->m_dldr.GetDownloadingSectionCount () != 0 &&
00261 (pThis->m_dldr.IsResumeSupported () == RST_PRESENT || pThis->m_dldr.GetNumberOfSections () > 1))
00262 {
00263 fsTicksMgr tickNow; tickNow.Now ();
00264 if (tickNow - tick0SpeedStart > 30*1000)
00265 {
00266 pThis->m_bNeedStartAgain = TRUE;
00267 pThis->StopDownload ();
00268 tick0SpeedStart.Now ();
00269 continue;
00270 }
00271 }
00272 else
00273 tick0SpeedStart.Now ();
00274 }
00275
00276 if (pThis->m_state & DS_NEEDADDSECTION)
00277 {
00278 pThis->m_state &= ~ DS_NEEDADDSECTION;
00279 pThis->AddSection ();
00280 }
00281
00282
00283 if (pThis->m_state & DS_NEEDADDSECTION2)
00284 {
00285 pThis->m_state &= ~ DS_NEEDADDSECTION2;
00286 if (pThis->m_dldr.GetStoppedSectionCount ())
00287 pThis->m_dldr.LaunchOneMoreSection ();
00288 else
00289 pThis->AddSection (FALSE);
00290 }
00291
00292 if (pThis->m_state & DS_NEEDRESTARTFROM)
00293 {
00294 pThis->m_state &= ~ DS_NEEDRESTARTFROM;
00295
00296 pThis->m_state |= DS_NEEDSTART;
00297 }
00298
00299 pThis->CheckMirrSpeedRecalcRequired ();
00300
00301 Sleep (100);
00302 }
00303
00304 if (bSSR)
00305 {
00306 if (pThis->m_dp.dwFlags & DPF_RETRDATEFROMSERVER)
00307 {
00308 if (pThis->m_hOutFile == INVALID_HANDLE_VALUE)
00309 {
00310 pThis->m_hOutFile = CreateFile (pThis->m_dp.pszFileName, GENERIC_WRITE,
00311 FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
00312 }
00313
00314 FILETIME time;
00315 GetFileTime (pThis->m_hOutFile, &time, NULL, NULL);
00316 ::SetFileTime (pThis->m_hOutFile, NULL, NULL, &time);
00317 }
00318
00319 pThis->CloseFile ();
00320 }
00321
00322 pThis->m_bThreadRunning = FALSE;
00323 pThis->Event (DE_EXTERROR, DMEE_STOPPEDORDONE);
00324
00325 InterlockedDecrement (&pThis->m_iThread);
00326
00327 return 0;
00328 }
00329
00330 DWORD fsDownloadMgr::_DownloaderEvents(fsDownloaderEvent enEvent, UINT uInfo, LPVOID lp)
00331 {
00332 fsDownloadMgr *pThis = (fsDownloadMgr*) lp;
00333 fsTicksMgr curTicks;
00334 CHAR szEv [1000], szErr [1000];
00335
00336 switch (enEvent)
00337 {
00338 case DE_SECTIONSTARTED:
00339
00340 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_STARTED));
00341 pThis->Event (szEv, EDT_RESPONSE_S);
00342 curTicks.Now ();
00343 if (curTicks - pThis->m_ticksStart < 1200)
00344 break;
00345 break;
00346
00347 case DE_SECTDOWNLOADING:
00348
00349 pThis->m_bCantStart = FALSE;
00350 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_DOWNLOADING));
00351 pThis->Event (szEv, EDT_RESPONSE_S);
00352 pThis->AddSection ();
00353 break;
00354
00355 case DE_MAYADDSECTION:
00356 pThis->AddSection ();
00357 break;
00358
00359 case DE_SPEEDISTOOLOW:
00360 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_SPEEDISTOOLOW));
00361 pThis->Event (szEv, EDT_WARNING);
00362 break;
00363
00364 case DE_SECTIONSTOPPED:
00365
00366 pThis->m_bCantStart = FALSE;
00367 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_SHESTOPPED));
00368 pThis->Event (szEv, EDT_RESPONSE_S);
00369 pThis->OnSectionStopped ();
00370 break;
00371
00372 case DE_SECTIONDONE:
00373
00374 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_DONE));
00375 pThis->Event (szEv, EDT_DONE);
00376
00377 if (pThis->m_dldr.IsDone () && (pThis->m_state & DS_DONE) == 0 && pThis->m_dldr.IsRunning () == FALSE)
00378 {
00379
00380 pThis->OnDone ();
00381 pThis->Event (LS (L_DLDCOMPLETED), EDT_DONE);
00382 pThis->Event (enEvent, uInfo);
00383 pThis->m_state = DS_DONE;
00384 return 0;
00385 }
00386 else
00387 {
00388 if (pThis->m_dldr.IsAllSectionsOk ())
00389 pThis->AddSection ();
00390 else
00391 pThis->OnSectionStopped ();
00392 }
00393 break;
00394
00395 case DE_ERROROCCURED:
00396 {
00397
00398 fsInternetResult ir = pThis->m_dldr.GetSectionLastError (uInfo);
00399 if (fsIRToStr (ir, szErr, sizeof (szErr)))
00400 {
00401 if (ir == IR_FILENOTFOUND)
00402 strcpy (szEv, szErr);
00403 else
00404 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, szErr);
00405 pThis->Event (szEv, EDT_RESPONSE_E);
00406 }
00407
00408 if (pThis->m_dldr.GetDownloadingSectionCount () == 0)
00409 pThis->m_bCantStart = TRUE;
00410 }
00411 break;
00412
00413 case DE_PAUSE:
00414 {
00415
00416 char szPause [1000];
00417 sprintf (szPause, LS (L_PAUSESECS), pThis->m_dp.uRetriesTime/1000);
00418 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, szPause);
00419 pThis->Event (szEv);
00420 }
00421 break;
00422
00423 case DE_CONNECTING:
00424
00425 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_CONNECTING));
00426 pThis->Event (szEv);
00427 break;
00428
00429 case DE_FAILCONNECT:
00430
00431 if (fsIRToStr (pThis->m_dldr.GetSectionLastError (uInfo), szErr, sizeof (szErr)))
00432 {
00433 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, szErr);
00434 pThis->Event (szEv, EDT_RESPONSE_E);
00435 }
00436 break;
00437
00438 case DE_BADFILESIZE:
00439 pThis->Event (LS (L_FILESIZESARENOTEQUAL), EDT_RESPONSE_E);
00440 break;
00441
00442 case DE_CONNECTED:
00443
00444 sprintf (szEv, "[%s %d] - %s", LS (L_SECTION), uInfo+1, LS (L_CONNSUCC));
00445 pThis->Event (szEv, EDT_RESPONSE_S);
00446 break;
00447
00448 case DE_WRITEERROR:
00449
00450 SetLastError (pThis->m_dldr.GetSectionLastError (uInfo));
00451 fsErrorToStr (szErr, sizeof (szErr));
00452 sprintf (szEv, "[%s %d] - %s - %s", LS (L_SECTION), uInfo+1, LS (L_WRITEERR), szErr);
00453 pThis->Event (szEv, EDT_RESPONSE_E);
00454 pThis->Event (DE_EXTERROR, DMEE_FATALERROR);
00455
00456 pThis->m_bFatalError = TRUE;
00457 break;
00458
00459 case DE_REDIRECTING:
00460
00461 pThis->Event (LS (L_REDIRECTING));
00462 break;
00463
00464 case DE_REDIRECTINGOKCONTINUEOPENING:
00465
00466 pThis->Event (LS (L_REDIRSUCC), EDT_RESPONSE_S);
00467 break;
00468
00469 case DE_NEEDFILE:
00470 if (FALSE == pThis->Event (DE_NEEDFILE, uInfo))
00471 return FALSE;
00472 return pThis->OnNeedFile ();
00473
00474 case DE_NEEDFILE_FINALINITIALIZATION:
00475 return pThis->OnNeedFile_FinalInit ();
00476
00477 case DE_SCR:
00478
00479 return pThis->OnSCR ();
00480
00481 case DE_QUERYNEWSECTION:
00482
00483 if (pThis->m_pfnEvents)
00484 {
00485
00486 return pThis->Event (DE_QUERYNEWSECTION, uInfo);
00487 }
00488 break;
00489
00490 case DE_ERRFROMSERVER:
00491 {
00492
00493 pThis->m_strExtError = (LPCSTR) uInfo;
00494 LPCSTR pszErr1 = pThis->m_strExtError;
00495 CHAR szErr [1000];
00496 fsIRToStr (IR_EXTERROR, szErr, 1000);
00497 pThis->Event (szErr, EDT_RESPONSE_E);
00498 pThis->Event (pszErr1, EDT_RESPONSE_E);
00499 }
00500 break;
00501
00502 case DE_RESTARTINGBECAUSENORANGES:
00503
00504 pThis->Event (LS (L_NORESUMERESTARTING), EDT_WARNING);
00505 break;
00506
00507 case DE_DIALOGWITHSERVER:
00508
00509 fsDlgWithServerInfo *info;
00510 info = (fsDlgWithServerInfo*) uInfo;
00511 pThis->Event (info->pszMsg, info->dir == IFDD_TOSERVER ? EDT_INQUIRY2 : EDT_RESPONSE_S2);
00512 break;
00513
00514 case DE_STARTINGSEARCHINGFORMIRRORS:
00515 pThis->Event (LS (L_SEARCHINGFORMIRRORS));
00516 break;
00517
00518 case DE_CONNECTINGMIRRSERVER:
00519 pThis->Event (LS (L_CONNECTINGSEARCHSERVER));
00520 break;
00521
00522 case DE_GETTINGMIRRSEARCHRESULTS:
00523 pThis->Event (LS (L_SUCCESS), EDT_RESPONSE_S);
00524 pThis->Event (LS (L_GETTINGRESULTS));
00525 break;
00526
00527 case DE_MEASURINGMIRRSPEED:
00528 pThis->m_tikLastMirrMeasureTime.Now ();
00529 pThis->Event (LS (L_CALCULATINGMIRRORSSPEED));
00530 break;
00531
00532 case DE_MIRRFOUND:
00533 char szEv [10000];
00534 sprintf (szEv, LS (L_NMIRRORSFOUND), pThis->m_dldr.GetFoundMirrorCount ());
00535 pThis->Event (szEv, EDT_RESPONSE_S);
00536 break;
00537
00538 case DE_MIRRDONE:
00539 pThis->Event (LS (L_MIRRORSEARCHINGDONE));
00540 break;
00541
00542 case DE_MIRRFAILED:
00543 pThis->Event (LS (L_FAILED), EDT_RESPONSE_E);
00544 break;
00545
00546 case DE_NOMIRRFOUND:
00547 pThis->Event (LS (L_NOMIRRORSFOUND), EDT_WARNING);
00548 break;
00549
00550 case DE_TRYINGANOTHERMIRROR:
00551 pThis->Event (LS (L_TRYINGANOTHERMIRROR));
00552 break;
00553
00554 case DE_FILESIZETOOBIG:
00555 pThis->Event (LS (L_FILESIZEEXCEEDS2GB), EDT_WARNING);
00556 break;
00557
00558 case DE_CONFIRMARCHIVEDETECTION:
00559 return pThis->Event (DE_CONFIRMARCHIVEDETECTION, uInfo);
00560
00561 case DE_ZIPPREVIEWSTARTED:
00562 pThis->Event ("ZIP preview is in progress...");
00563 break;
00564
00565 case DE_ZIPPREVIEWFAILED:
00566 pThis->Event ("ZIP preview failed", EDT_RESPONSE_E);
00567 pThis->Event (DE_EXTERROR, DMEE_FATALERROR);
00568 pThis->m_bFatalError = TRUE;
00569 break;
00570
00571 case DE_ARCHIVEDETECTED:
00572 pThis->Event ("ZIP preview succeded", EDT_RESPONSE_S);
00573 return pThis->Event (DE_ARCHIVEDETECTED, uInfo);
00574 }
00575
00576 pThis->Event (enEvent, uInfo);
00577 return TRUE;
00578 }
00579
00580 fsInternetDownloader* fsDownloadMgr::GetDownloader()
00581 {
00582 return &m_dldr;
00583 }
00584
00585 fsInternetResult fsDownloadMgr::CreateByUrl(LPCSTR pszUrl, BOOL bAcceptHTMLPathes)
00586 {
00587 fsDNP_BuffersInfo buffs;
00588 fsDNP_GetByUrl_Free (m_dldr.DNP ());
00589
00590 CString strURL = pszUrl;
00591 strURL.Replace ("<", "<");
00592 strURL.Replace (">", ">");
00593 strURL.Replace ("&", "&");
00594 strURL.Replace (""", "\"");
00595
00596 fsInternetResult ir = fsDNP_GetByUrl (m_dldr.DNP (), &buffs, TRUE, strURL);
00597 if (ir != IR_SUCCESS)
00598 return ir;
00599
00600 LPCSTR pszPathName = m_dldr.DNP ()->pszPathName;
00601 int len = lstrlen (pszPathName);
00602
00603
00604 if (pszPathName == NULL || len == 0 || pszPathName [len-1] == '\\' || pszPathName [len-1] == '/')
00605 {
00606 if (bAcceptHTMLPathes == FALSE || (m_dldr.DNP ()->enProtocol != NP_HTTP && m_dldr.DNP ()->enProtocol != NP_HTTPS) )
00607 return IR_BADURL;
00608 }
00609
00610 return IR_SUCCESS;
00611 }
00612
00613 fsInternetResult fsDownloadMgr::StartDownload()
00614 {
00615 fsInternetResult ir;
00616
00617 Event (LS (L_STARTINGDLD));
00618 m_bFatalError = FALSE;
00619
00620 ir = CreateInternetSession ();
00621 if (ir != IR_SUCCESS)
00622 return ir;
00623
00624 ApplyProperties ();
00625
00626 ir = m_dldr.StartDownloading (m_uNeedStartFrom);
00627
00628 if (ir != IR_SUCCESS && ir != IR_S_FALSE && ir != IR_EXTERROR)
00629 {
00630 CHAR szEv [1000];
00631 BOOL bEv = FALSE;
00632
00633 bEv = fsIRToStr (ir, szEv, sizeof (szEv));
00634
00635 if (bEv)
00636 Event (szEv, EDT_RESPONSE_E);
00637
00638 switch (ir)
00639 {
00640 case IR_FILENOTFOUND:
00641
00642 if (m_dp.aEP [DFE_NOTFOUND] == DFEP_STOP)
00643 ir = IR_S_FALSE;
00644 break;
00645
00646 case IR_LOGINFAILURE:
00647 case IR_INVALIDPASSWORD:
00648 case IR_INVALIDUSERNAME:
00649
00650 if (m_dp.aEP [DFE_ACCDENIED] == DFEP_STOP)
00651 ir = IR_S_FALSE;
00652 break;
00653 }
00654
00655 if (ir == IR_S_FALSE)
00656 {
00657 m_state |= DS_NEEDSTOP;
00658 Event (DE_EXTERROR, DMEE_FATALERROR);
00659 m_bFatalError = TRUE;
00660 }
00661 }
00662
00663 if (ir == IR_S_FALSE && m_dldr.IsRunning () == FALSE &&
00664 (m_state & DS_NEEDRESTARTFROM) == 0)
00665 m_state |= DS_NEEDSTOP;
00666
00667 m_ticksStart.Now ();
00668
00669 return ir;
00670 }
00671
00672 void fsDownloadMgr::StopDownloading()
00673 {
00674 if (IsRunning ())
00675 {
00676 m_state |= DS_NEEDSTOP;
00677 m_dldr.StopDownloading ();
00678 #ifndef FDM_DLDR__RAWCODEONLY
00679 if (m_mdc)
00680 m_mdc->Stop ();
00681 #endif
00682 }
00683 }
00684
00685 void fsDownloadMgr::StopDownload()
00686 {
00687 if (m_dldr.IsRunning ())
00688 {
00689 #ifndef FDM_DLDR__RAWCODEONLY
00690 if (m_mdc)
00691 m_mdc->Stop ();
00692 #endif
00693 m_dldr.StopDownloading ();
00694 while (m_dldr.IsRunning ())
00695 Sleep (10);
00696 }
00697 }
00698
00699 void fsDownloadMgr::SetOutputFileName(LPCSTR pszName)
00700 {
00701 SAFE_DELETE_ARRAY (m_dp.pszFileName);
00702
00703 fsnew (m_dp.pszFileName, CHAR, strlen (pszName)+1);
00704 strcpy (m_dp.pszFileName, pszName);
00705 }
00706
00707 void fsDownloadMgr::SetEventFunc(fntDownloadMgrEventFunc pfnEvents, LPVOID lpParam)
00708 {
00709 m_pfnEvents = pfnEvents;
00710 m_lpParamEvents = lpParam;
00711 }
00712
00713 void fsDownloadMgr::SetEventDescFunc(fntEventDescFunc pfn, LPVOID lpParam)
00714 {
00715 m_pfnEventDesc = pfn;
00716 m_lpEventDescParam = lpParam;
00717 }
00718
00719 void fsDownloadMgr::Event(LPCSTR pszEvent, fsDownloadMgr_EventDescType enType)
00720 {
00721 if (m_pfnEventDesc && *pszEvent)
00722 m_pfnEventDesc (this, enType, pszEvent, m_lpEventDescParam);
00723 }
00724
00725 void fsDownloadMgr::AddSection(BOOL bCheckAdm)
00726 {
00727 LOG ("Entering DLM::AddSection..." << nl);
00728
00729 if (m_bDontCreateNewSections || m_dldr.IsSectionCreatingNow ())
00730 {
00731 LOG ("Exit DLM::AddSection" << nl);
00732 return;
00733 }
00734
00735 if (bCheckAdm == FALSE || IsSectionCanBeAdded ())
00736 {
00737 if (m_dldr.GetSectionMaxSize () > m_dp.uSectionMinSize)
00738 {
00739 Event (LS (L_NEWSECTION));
00740 m_lastError = m_dldr.AddSection (bCheckAdm);
00741
00742 if (m_lastError != IR_SUCCESS)
00743 {
00744 if (m_lastError == IR_S_FALSE)
00745 Event (LS (L_CANCELED), EDT_RESPONSE_S);
00746 else
00747 {
00748 CHAR szEv [1000];
00749 if (fsIRToStr (m_lastError, szEv, sizeof (szEv)))
00750 Event (szEv, EDT_RESPONSE_E);
00751 }
00752 }
00753 }
00754 }
00755
00756 LOG ("Exit DLM::AddSection" << nl);
00757 }
00758
00759 BOOL fsDownloadMgr::IsDone()
00760 {
00761 return m_dldr.IsDone ();
00762 }
00763
00764 BOOL fsDownloadMgr::SaveState(LPVOID lpBuffer, LPDWORD pdwSize)
00765 {
00766 DWORD dwNeedSize;
00767 fsDownload_Properties dp = m_dp;
00768 fsDownload_NetworkProperties dnp = *GetDNP ();
00769 fs::list <fsDownload_NetworkProperties> vDNPs;
00770
00771 LPCSTR ToSave [3000];
00772 DWORD ToSaveLen [3000];
00773 UINT cToSave = 0;
00774
00775 if (FALSE == m_dldr.SaveSectionsState (NULL, &dwNeedSize))
00776 return FALSE;
00777
00778 dwNeedSize += sizeof (DWORD);
00779 dwNeedSize += sizeof (dp);
00780 dwNeedSize += sizeof (dnp);
00781 dwNeedSize += sizeof (m_state);
00782 dwNeedSize += sizeof (m_dwDownloadFileFlags);
00783 dwNeedSize += sizeof (int);
00784
00785 dp.pszFileName = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dp.pszFileName));
00786 dwNeedSize += (DWORD) dp.pszFileName;
00787
00788 dp.pszAdditionalExt = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dp.pszAdditionalExt));
00789 dwNeedSize += (DWORD) dp.pszAdditionalExt;
00790
00791 dp.pszCreateExt = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dp.pszCreateExt));
00792 dwNeedSize += (DWORD) dp.pszCreateExt;
00793
00794 dp.pszCheckSum = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dp.pszCheckSum));
00795 dwNeedSize += (DWORD) dp.pszCheckSum;
00796
00797 int cDPStrings = cToSave;
00798
00799 for (UINT i = 0; int (i) < m_dldr.GetMirrorURLCount () + 1; i++)
00800 {
00801 if (i)
00802 {
00803 dnp = *m_dldr.MirrorDNP (i-1);
00804 dwNeedSize += sizeof (dnp);
00805 }
00806
00807 dnp.pszAgent = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszAgent));
00808 dnp.pszPassword = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszPassword));
00809 dnp.pszPathName = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszPathName));
00810 dnp.pszProxyName = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszProxyName));
00811 dnp.pszProxyPassword = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszProxyPassword));
00812 dnp.pszProxyUserName = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszProxyUserName));
00813 dnp.pszReferer = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszReferer));
00814 dnp.pszServerName = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszServerName));
00815 dnp.pszUserName = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszUserName));
00816 dnp.pszASCIIExts = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszASCIIExts));
00817 dnp.pszCookies = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszCookies));
00818 dnp.pszPostData = LPSTR (ToSaveLen [cToSave++] = strlen (ToSave [cToSave] = dnp.pszPostData));
00819
00820 vDNPs.add (dnp);
00821
00822 dwNeedSize += (DWORD) dnp.pszAgent + (DWORD) dnp.pszPassword +
00823 (DWORD) dnp.pszPathName + (DWORD) dnp.pszProxyName +
00824 (DWORD) dnp.pszProxyPassword + (DWORD) dnp.pszProxyUserName +
00825 (DWORD) dnp.pszReferer + (DWORD) dnp.pszServerName + (DWORD) dnp.pszUserName +
00826 (DWORD) dnp.pszASCIIExts + (DWORD) dnp.pszCookies + (DWORD) dnp.pszPostData;
00827 }
00828
00829 dwNeedSize += m_dldr.GetMirrorURLCount () * sizeof (BOOL);
00830
00831 if (m_dldr.GetMirrorURLCount ())
00832 {
00833 dwNeedSize += m_dldr.GetMirrorURLCount () * sizeof (DWORD);
00834 dwNeedSize += sizeof (DWORD);
00835 }
00836
00837 if (lpBuffer == NULL)
00838 {
00839 *pdwSize = dwNeedSize;
00840 return TRUE;
00841 }
00842
00843 if (*pdwSize < dwNeedSize)
00844 {
00845 *pdwSize = dwNeedSize;
00846 return FALSE;
00847 }
00848
00849 int cDNPStrings;
00850 cDNPStrings = (cToSave - cDPStrings) / (m_dldr.GetMirrorURLCount () + 1);
00851
00852 DWORD dw = *pdwSize;
00853 LPBYTE pB = (LPBYTE) lpBuffer;
00854
00855 if (FALSE == m_dldr.SaveSectionsState (pB + sizeof (DWORD), &dw))
00856 return FALSE;
00857
00858 CopyMemory (pB, &dw, sizeof (dw));
00859 pB += dw + sizeof (dw);
00860
00861 CopyMemory (pB, &dp, sizeof (dp));
00862 pB += sizeof (dp);
00863
00864 CopyMemory (pB, &vDNPs [0], sizeof (dnp));
00865 pB += sizeof (dnp);
00866
00867 fsDownloadState state = (m_state & DS_DONE) ? DS_DONE : 0;
00868 CopyMemory (pB, &state, sizeof (state));
00869 pB += sizeof (state);
00870
00871 if ((m_dwDownloadFileFlags & DFF_USE_PORTABLE_DRIVE) &&
00872 m_dp.pszFileName [0] != vmsGetExeDriveLetter ())
00873 m_dwDownloadFileFlags &= ~DFF_USE_PORTABLE_DRIVE;
00874 CopyMemory (pB, &m_dwDownloadFileFlags, sizeof (m_dwDownloadFileFlags));
00875 pB += sizeof (m_dwDownloadFileFlags);
00876
00877 int cMirrs = m_dldr.GetMirrorURLCount ();
00878 CopyMemory (pB, &cMirrs, sizeof (cMirrs));
00879 pB += sizeof (cMirrs);
00880
00881 for (i = 0; i < cToSave; i++)
00882 {
00883 if (i > UINT (cDPStrings) && ((i-cDPStrings) % cDNPStrings) == 0)
00884 {
00885 CopyMemory (pB, &vDNPs [(i-cDPStrings) / cDNPStrings], sizeof (dnp));
00886 pB += sizeof (dnp);
00887
00888 BOOL b = m_dldr.GetMirrorIsGood ((i-cDPStrings) / cDNPStrings - 1);
00889 CopyMemory (pB, &b, sizeof (b));
00890 pB += sizeof (b);
00891 }
00892
00893 CopyMemory (pB, ToSave [i], ToSaveLen [i]);
00894 pB += ToSaveLen [i];
00895 }
00896
00897 if (cMirrs)
00898 {
00899 for (i = 0; i < UINT (cMirrs); i++)
00900 {
00901 DWORD dw = m_dldr.GetMirrorPingTime (i);
00902 CopyMemory (pB, &dw, sizeof (dw));
00903 pB += sizeof (dw);
00904 }
00905
00906 DWORD dw = m_dldr.Get_BaseServerPingTime ();
00907 CopyMemory (pB, &dw, sizeof (dw));
00908 pB += sizeof (dw);
00909 }
00910
00911 *pdwSize = dwNeedSize;
00912
00913 return TRUE;
00914 }
00915
00916 BOOL fsDownloadMgr::LoadState(LPVOID lpBuffer, LPDWORD pdwSize, WORD wVer)
00917 {
00918 #define CHECK_BOUNDS(need) if (need < 0 || need > int(*pdwSize) - (pB - LPBYTE (lpBuffer))) return FALSE;
00919
00920 DWORD dw = *pdwSize;
00921 LPBYTE pB = (LPBYTE) lpBuffer;
00922
00923 CHECK_BOUNDS (sizeof (DWORD));
00924
00925 CopyMemory (&dw, pB, sizeof (DWORD));
00926 pB += sizeof (DWORD);
00927
00928 CHECK_BOUNDS (int (dw));
00929
00930 if (FALSE == m_dldr.RestoreSectionsState (pB, dw, wVer))
00931 return FALSE;
00932 pB += dw;
00933
00934 CHECK_BOUNDS (sizeof (m_dp));
00935
00936 DWORD dwDP = sizeof (fsDownload_Properties);
00937 if (wVer < 8)
00938 dwDP -= sizeof (BOOL) + sizeof (vmsIntegrityCheckFailedReaction) + sizeof (LPSTR) + sizeof (DWORD);
00939 if (wVer == 2)
00940 dwDP -= sizeof (LPSTR);
00941 CopyMemory (&m_dp, pB, dwDP);
00942 pB += dwDP;
00943
00944 fsDownload_NetworkProperties *dnp = GetDNP ();
00945 DWORD dwDNP = sizeof (fsDownload_NetworkProperties);
00946 if (wVer < 7)
00947 dwDNP -= 2 * sizeof (LPSTR) + sizeof (DWORD) + 2 * sizeof (WORD);
00948 CHECK_BOUNDS ((int)dwDNP);
00949 CopyMemory (dnp, pB, dwDNP);
00950 pB += dwDNP;
00951
00952 CHECK_BOUNDS (sizeof (m_state));
00953
00954 CopyMemory (&m_state, pB, sizeof (m_state));
00955 pB += sizeof (m_state);
00956
00957 if (wVer == 0)
00958 {
00959 m_dwDownloadFileFlags = m_dldr.GetNumberOfSections () == 0 ? DFF_NEED_INIT_FILE : 0;
00960 }
00961 else
00962 {
00963 CHECK_BOUNDS (sizeof (m_dwDownloadFileFlags));
00964
00965 CopyMemory (&m_dwDownloadFileFlags, pB, sizeof (m_dwDownloadFileFlags));
00966 pB += sizeof (m_dwDownloadFileFlags);
00967 }
00968
00969 int cMirrs = 0;
00970 if (wVer > 3)
00971 {
00972 CHECK_BOUNDS (sizeof (int));
00973
00974 CopyMemory (&cMirrs, pB, sizeof (int));
00975 pB += sizeof (int);
00976 }
00977
00978 dw = DWORD (m_dp.pszFileName);
00979 CHECK_BOUNDS (int (dw));
00980 fsnew (m_dp.pszFileName, CHAR, dw+1);
00981 CopyMemory (m_dp.pszFileName, pB, dw);
00982 m_dp.pszFileName [dw] = 0;
00983 pB += dw;
00984 if (m_dwDownloadFileFlags & DFF_USE_PORTABLE_DRIVE)
00985 m_dp.pszFileName [0] = vmsGetExeDriveLetter ();
00986
00987 dw = DWORD (m_dp.pszAdditionalExt);
00988 CHECK_BOUNDS (int (dw));
00989 fsnew (m_dp.pszAdditionalExt, CHAR, dw+1);
00990 CopyMemory (m_dp.pszAdditionalExt, pB, dw);
00991 m_dp.pszAdditionalExt [dw] = 0;
00992 pB += dw;
00993
00994 if (wVer > 2)
00995 {
00996 dw = DWORD (m_dp.pszCreateExt);
00997 CHECK_BOUNDS (int (dw));
00998 fsnew (m_dp.pszCreateExt, CHAR, dw+1);
00999 CopyMemory (m_dp.pszCreateExt, pB, dw);
01000 m_dp.pszCreateExt [dw] = 0;
01001 pB += dw;
01002 }
01003 else
01004 {
01005 fsnew (m_dp.pszCreateExt, CHAR, 1);
01006 *m_dp.pszCreateExt = 0;
01007 }
01008
01009 if (wVer > 7)
01010 {
01011 dw = DWORD (m_dp.pszCheckSum);
01012 CHECK_BOUNDS (int (dw));
01013 fsnew (m_dp.pszCheckSum, CHAR, dw+1);
01014 CopyMemory (m_dp.pszCheckSum, pB, dw);
01015 m_dp.pszCheckSum [dw] = 0;
01016 pB += dw;
01017 }
01018 else
01019 {
01020 fsnew (m_dp.pszCheckSum, CHAR, 1);
01021 *m_dp.pszCheckSum = 0;
01022 m_dp.bCheckIntegrityWhenDone = FALSE;
01023 m_dp.dwIntegrityCheckAlgorithm = HA_MD5;
01024 }
01025
01026 for (int i = 0; i < cMirrs + 1; i++)
01027 {
01028 fsDownload_NetworkProperties tmpdnp;
01029 BOOL bMirrIsGood;
01030
01031 if (i)
01032 {
01033 dnp = &tmpdnp;
01034
01035 CHECK_BOUNDS ((int)dwDNP);
01036 CopyMemory (dnp, pB, dwDNP);
01037 pB += dwDNP;
01038
01039 CHECK_BOUNDS (sizeof (BOOL));
01040
01041 CopyMemory (&bMirrIsGood, pB, sizeof (BOOL));
01042 pB += sizeof (BOOL);
01043 }
01044
01045 dw = DWORD (dnp->pszAgent);
01046 CHECK_BOUNDS (int (dw));
01047 fsnew (dnp->pszAgent, CHAR, dw+1);
01048 CopyMemory (dnp->pszAgent, pB, dw);
01049 dnp->pszAgent [dw] = 0;
01050 pB += dw;
01051
01052 dw = DWORD (dnp->pszPassword);
01053 CHECK_BOUNDS (int (dw));
01054 fsnew (dnp->pszPassword, CHAR, dw+1);
01055 CopyMemory (dnp->pszPassword, pB, dw);
01056 dnp->pszPassword [dw] = 0;
01057 pB += dw;
01058
01059 dw = DWORD (dnp->pszPathName);
01060 CHECK_BOUNDS (int (dw));
01061 fsnew (dnp->pszPathName, CHAR, dw+1);
01062 CopyMemory (dnp->pszPathName, pB, dw);
01063 dnp->pszPathName [dw] = 0;
01064 pB += dw;
01065
01066 dw = DWORD (dnp->pszProxyName);
01067 CHECK_BOUNDS (int (dw));
01068 fsnew (dnp->pszProxyName, CHAR, dw+1);
01069 CopyMemory (dnp->pszProxyName, pB, dw);
01070 dnp->pszProxyName [dw] = 0;
01071 pB += dw;
01072
01073 dw = DWORD (dnp->pszProxyPassword);
01074 CHECK_BOUNDS (int (dw));
01075 fsnew (dnp->pszProxyPassword, CHAR, dw+1);
01076 CopyMemory (dnp->pszProxyPassword, pB, dw);
01077 dnp->pszProxyPassword [dw] = 0;
01078 pB += dw;
01079
01080 dw = DWORD (dnp->pszProxyUserName);
01081 CHECK_BOUNDS (int (dw));
01082 fsnew (dnp->pszProxyUserName, CHAR, dw+1);
01083 CopyMemory (dnp->pszProxyUserName, pB, dw);
01084 dnp->pszProxyUserName [dw] = 0;
01085 pB += dw;
01086
01087 dw = DWORD (dnp->pszReferer);
01088 CHECK_BOUNDS (int (dw));
01089 fsnew (dnp->pszReferer, CHAR, dw+1);
01090 CopyMemory (dnp->pszReferer, pB, dw);
01091 dnp->pszReferer [dw] = 0;
01092 pB += dw;
01093
01094 dw = DWORD (dnp->pszServerName);
01095 CHECK_BOUNDS (int (dw));
01096 fsnew (dnp->pszServerName, CHAR, dw+1);
01097 CopyMemory (dnp->pszServerName, pB, dw);
01098 dnp->pszServerName [dw] = 0;
01099 pB += dw;
01100
01101 dw = DWORD (dnp->pszUserName);
01102 CHECK_BOUNDS (int (dw));
01103 fsnew (dnp->pszUserName, CHAR, dw+1);
01104 CopyMemory (dnp->pszUserName, pB, dw);
01105 dnp->pszUserName [dw] = 0;
01106 pB += dw;
01107
01108 dw = DWORD (dnp->pszASCIIExts);
01109 CHECK_BOUNDS (int (dw));
01110 fsnew (dnp->pszASCIIExts, CHAR, dw+1);
01111 CopyMemory (dnp->pszASCIIExts, pB, dw);
01112 dnp->pszASCIIExts [dw] = 0;
01113 pB += dw;
01114
01115 if (wVer > 6)
01116 {
01117
01118 dw = DWORD (dnp->pszCookies);
01119 CHECK_BOUNDS (int (dw));
01120 fsnew (dnp->pszCookies, CHAR, dw+1);
01121 CopyMemory (dnp->pszCookies, pB, dw);
01122 dnp->pszCookies [dw] = 0;
01123 pB += dw;
01124
01125 dw = DWORD (dnp->pszPostData);
01126 CHECK_BOUNDS (int (dw));
01127 fsnew (dnp->pszPostData, CHAR, dw+1);
01128 CopyMemory (dnp->pszPostData, pB, dw);
01129 dnp->pszPostData [dw] = 0;
01130 pB += dw;
01131 }
01132 else
01133 {
01134 dnp->pszCookies = new char [1];
01135 dnp->pszCookies [0] = 0;
01136
01137 dnp->pszPostData = new char [1];
01138 dnp->pszPostData [0] = 0;
01139
01140 dnp->dwFlags = 0;
01141 dnp->wLowSpeed_Factor = 4;
01142 dnp->wLowSpeed_Duration = 1;
01143 }
01144
01145 if (i)
01146 m_dldr.AddMirror (dnp, TRUE, TRUE);
01147 }
01148
01149 if (cMirrs)
01150 {
01151 for (i = 0; i < cMirrs; i++)
01152 {
01153 DWORD dw;
01154
01155 CHECK_BOUNDS (sizeof (dw));
01156
01157 CopyMemory (&dw, pB, sizeof (dw));
01158 pB += sizeof (dw);
01159
01160 m_dldr.Set_MirrPingTime (i, dw);
01161 }
01162
01163 DWORD dw;
01164
01165 CHECK_BOUNDS (sizeof (dw));
01166
01167 CopyMemory (&dw, pB, sizeof (dw));
01168 pB += sizeof (dw);
01169
01170 m_dldr.Set_BaseServerPingTime (dw);
01171 }
01172
01173 *pdwSize = pB - (LPBYTE) lpBuffer;
01174
01175 return TRUE;
01176 }
01177
01178 BOOL fsDownloadMgr::IsRunning()
01179 {
01180 return m_bThreadRunning || m_dldr.IsRunning ();
01181 }
01182
01183 BOOL fsDownloadMgr::SleepInterval()
01184 {
01185 int i = m_dp.uRetriesTime;
01186
01187 while (i > 0)
01188 {
01189 Sleep (100);
01190 i -= 100;
01191
01192 if (m_state & DS_NEEDSTOP)
01193 return FALSE;
01194 }
01195
01196 return TRUE;
01197 }
01198
01199 void fsDownloadMgr::OnSectionStopped()
01200 {
01201 if (m_dldr.IsRunning () == FALSE)
01202 {
01203 m_state &= ~DS_DOWNLOADING;
01204
01205 if ((m_bNeedStartAgain || m_dldr.IsStoppedByUser () == FALSE) &&
01206 m_bFatalError == FALSE)
01207 {
01208 m_bNeedStartAgain = FALSE;
01209 Event (LS (L_RESTARTINGDLD));
01210 m_state |= DS_NEEDSTART;
01211 }
01212 else
01213 {
01214 m_state |= DS_NEEDSTOP;
01215 }
01216 }
01217 }
01218
01219 BOOL fsDownloadMgr::OnNeedFile()
01220 {
01221 BOOL bOk;
01222
01223 if (m_hOutFile != INVALID_HANDLE_VALUE)
01224 {
01225
01226 m_dldr.SetOutputFile (m_hOutFile);
01227 return TRUE;
01228 }
01229
01230 Event (LS (L_OPENINGFILE));
01231
01232 if (m_dwDownloadFileFlags & DFF_NEED_INIT_FILE)
01233 {
01234 if (FALSE == InitFile ())
01235 {
01236 Event (DE_EXTERROR, DMEE_FATALERROR);
01237 m_bFatalError = TRUE;
01238 return FALSE;
01239 }
01240 }
01241
01242 bOk = OpenFile ();
01243
01244 if (!bOk)
01245 goto _lErr;
01246 else if (bOk == BOOL (-1))
01247 return FALSE;
01248
01249 m_dldr.SetOutputFile (m_hOutFile);
01250 Event (LS (L_SUCCESS), EDT_RESPONSE_S);
01251
01252 return TRUE;
01253
01254 _lErr:
01255 DescribeAPIError ();
01256 m_state |= DS_NEEDSTOP;
01257 Event (DE_EXTERROR, DMEE_FATALERROR);
01258 m_bFatalError = TRUE;
01259 return FALSE;
01260 }
01261
01262 void fsDownloadMgr::RenameFile(BOOL bFormat1)
01263 {
01264 int i = 1;
01265 DWORD dwResult;
01266 CHAR szFileWE [MY_MAX_PATH];
01267 CString strFile;
01268
01269 strcpy (szFileWE, m_dp.pszFileName);
01270
01271 if (m_dp.pszAdditionalExt && *m_dp.pszAdditionalExt)
01272 {
01273 int fl = strlen (szFileWE);
01274 int al = strlen (m_dp.pszAdditionalExt);
01275
01276 if (fl > al && szFileWE [fl - al - 1] == '.' &&
01277 stricmp (szFileWE + fl - al, m_dp.pszAdditionalExt) == 0)
01278 {
01279 szFileWE [fl - al - 1] = 0;
01280 }
01281
01282 }
01283
01284 LPSTR pszExt = strrchr (szFileWE, '.');
01285 LPSTR pszDirEnd = strrchr (szFileWE, '\\');
01286
01287 if (pszExt != NULL && pszDirEnd > pszExt)
01288 pszExt = NULL;
01289
01290 if (pszExt)
01291 *pszExt = 0;
01292
01293 if (m_bRename_CheckIfRenamed)
01294 {
01295 int l = lstrlen (szFileWE);
01296 if (szFileWE [l-1] == ')')
01297 {
01298 LPSTR psz = szFileWE + l - 2;
01299 while (*psz && *psz >= '0' && *psz <= '9')
01300 psz--;
01301 if (*psz == '(')
01302
01303
01304 *psz = 0;
01305 }
01306 }
01307
01308 m_csRenameFile.Lock ();
01309
01310 do
01311 {
01312 if (pszExt)
01313 strFile.Format ("%s(%d).%s", szFileWE, i++, pszExt+1);
01314 else
01315 strFile.Format ("%s(%d)", szFileWE, i++);
01316
01317 dwResult = GetFileAttributes (strFile);
01318 }
01319 while (dwResult != DWORD (-1));
01320
01321 SAFE_DELETE_ARRAY (m_dp.pszFileName);
01322 fsnew (m_dp.pszFileName, CHAR, strFile.GetLength () + 1);
01323 strcpy (m_dp.pszFileName, strFile);
01324
01325 HANDLE hFile = CreateFile (m_dp.pszFileName, GENERIC_WRITE, 0, NULL,
01326 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
01327 if (hFile != INVALID_HANDLE_VALUE)
01328 CloseHandle (hFile);
01329
01330 m_csRenameFile.Unlock ();
01331
01332 CHAR szFileName [MY_MAX_PATH];
01333 fsGetFileName (strFile, szFileName);
01334 CString strEv;
01335 if (bFormat1)
01336 strEv.Format ("%s \"%s\"", LS (L_FILEALREXISTSRENAMING), szFileName);
01337 else
01338 strEv.Format ("%s %s", LS (L_RENAMINGTO), szFileName);
01339
01340 Event (strEv, EDT_WARNING);
01341 Event (DE_EXTERROR, DMEE_FILEUPDATED);
01342 }
01343
01344 BOOL fsDownloadMgr::OpenFile(BOOL bFailIfDeleted, BOOL bDisableEvents)
01345 {
01346 if (m_hOutFile != INVALID_HANDLE_VALUE)
01347 return TRUE;
01348
01349 if (bFailIfDeleted && GetFileAttributes (m_dp.pszFileName) == DWORD (-1) && m_dldr.GetNumberOfSections ())
01350 {
01351 fsSection sect;
01352 m_dldr.GetSectionInfo (0, §);
01353
01354 if (m_dldr.GetNumberOfSections () != 1 || sect.uCurrent != sect.uStart)
01355 {
01356
01357 if (bDisableEvents == FALSE)
01358 Event (LS (L_WASDELETED), EDT_RESPONSE_E);
01359 m_state |= DS_NEEDSTOP;
01360 if (bDisableEvents == FALSE)
01361 Event (DE_EXTERROR, DMEE_FILEWASDELETED);
01362 return -1;
01363 }
01364 }
01365
01366 DWORD dwFileAttribs = FILE_ATTRIBUTE_NORMAL;
01367
01368 m_hOutFile = CreateFile (m_dp.pszFileName, GENERIC_WRITE, FILE_SHARE_READ,
01369 NULL, OPEN_ALWAYS, dwFileAttribs, NULL);
01370
01371 DWORD dw = GetFileAttributes (m_dp.pszFileName);
01372 if ((m_dp.dwFlags & DPF_USEHIDDENATTRIB) && (dw & FILE_ATTRIBUTE_HIDDEN) == 0)
01373 SetFileAttributes (m_dp.pszFileName, dw | FILE_ATTRIBUTE_HIDDEN);
01374
01375 if (m_hOutFile == INVALID_HANDLE_VALUE)
01376 return FALSE;
01377
01378 if (::GetLastError () != ERROR_ALREADY_EXISTS)
01379 SetFileTime (m_hOutFile);
01380
01381 return TRUE;
01382 }
01383
01384 BOOL fsDownloadMgr::ApplyAER(fsAlreadyExistReaction enAER)
01385 {
01386 switch (enAER)
01387 {
01388 case AER_ASKUSER:
01389 {
01390 #if !defined (FDM_DLDR__RAWCODEONLY)
01391 CAERDlg dlg;
01392 dlg.m_pszFile = m_dp.pszFileName;
01393 _DlgMgr.OnDoModal (&dlg);
01394 dlg.DoModal ();
01395 _DlgMgr.OnEndDialog (&dlg);
01396 if (dlg.m_bDontAskAgain)
01397 {
01398 m_dp.enAER = dlg.m_enAER;
01399 _App.AlreadyExistReaction (dlg.m_enAER);
01400 _DldsMgr.ApplyAER (dlg.m_enAER);
01401 }
01402 enAER = dlg.m_enAER;
01403 #else
01404 enAER = AER_REWRITE;
01405 #endif
01406 return ApplyAER (enAER);
01407 }
01408
01409 case AER_REWRITE:
01410 if (!OpenFile ())
01411 return FALSE;
01412 Event (LS (L_REWRITINGIT), EDT_WARNING);
01413 SetFilePointer (m_hOutFile, 0, NULL, FILE_BEGIN);
01414 SetEndOfFile (m_hOutFile);
01415 return TRUE;
01416
01417 case AER_RENAME_2:
01418 case AER_RENAME:
01419 RenameFile ();
01420 return TRUE;
01421
01422 case AER_RESUME:
01423 if (!OpenFile ())
01424 return FALSE;
01425 m_uNeedStartFrom = GetFileSize (m_hOutFile, NULL);
01426 Event (LS (L_RESUMINGDLD), EDT_WARNING);
01427 m_state |= DS_NEEDRESTARTFROM;
01428 return -1;
01429
01430 case AER_STOP:
01431 Event (LS (L_ALREXISTS), EDT_RESPONSE_E);
01432 m_state |= DS_NEEDSTOP;
01433 Event (DE_EXTERROR, DMEE_USERSTOP);
01434 return -1;
01435
01436 default:
01437 ASSERT (FALSE);
01438 return FALSE;
01439 }
01440 }
01441
01442 DWORD fsDownloadMgr::Event(fsDownloaderEvent ev, UINT uInfo)
01443 {
01444 if (m_pfnEvents)
01445 return m_pfnEvents (this, ev, uInfo, m_lpParamEvents);
01446
01447 return TRUE;
01448 }
01449
01450 BOOL fsDownloadMgr::BuildFileName(LPCSTR pszSetExt)
01451 {
01452 CHAR szFile [MY_MAX_PATH];
01453 CHAR szPath [MY_MAX_PATH];
01454
01455 int fl = strlen (m_dp.pszFileName);
01456
01457 if (m_dp.pszFileName [fl - 1] != '/' && m_dp.pszFileName [fl - 1] != '\\')
01458 return TRUE;
01459
01460 LPCSTR pszSuggFile = m_dldr.GetSuggestedFileName ();
01461 if (pszSuggFile && *pszSuggFile)
01462 strcpy (szFile, pszSuggFile);
01463 else
01464 {
01465
01466 if (!fsFileNameFromUrlPath (GetDNP ()->pszPathName, GetDNP ()->enProtocol == NP_FTP,
01467 TRUE, szFile, sizeof (szFile)))
01468 return FALSE;
01469 }
01470
01471 if (*szFile == 0)
01472 strcpy (szFile, "index.html");
01473
01474
01475 LPSTR psz = szFile;
01476 char szSymbls [] = {":*?\"<>|"};
01477 while (*psz) {
01478 if (strchr (szSymbls, *psz))
01479 *psz = ' ';
01480 psz++;
01481 }
01482
01483 if (fl >= MY_MAX_PATH - 1)
01484 return FALSE;
01485
01486 szFile [MY_MAX_PATH - 1 - fl] = 0;
01487
01488 char *pszExt = strrchr (szFile, '.');
01489
01490 if (pszSetExt)
01491 {
01492 if (pszExt == NULL)
01493 {
01494 strcat (szFile, ".");
01495 strcat (szFile, pszSetExt);
01496 }
01497 else
01498 {
01499 strcpy (pszExt+1, pszSetExt);
01500 }
01501 }
01502 else if (pszExt == NULL && m_dp.pszCreateExt && *m_dp.pszCreateExt)
01503 {
01504
01505 strcat (szFile, ".");
01506 strcat (szFile, m_dp.pszCreateExt);
01507 }
01508
01509 strcpy (szPath, m_dp.pszFileName);
01510 strcat (szPath, szFile);
01511
01512 SAFE_DELETE_ARRAY (m_dp.pszFileName);
01513 fsnew (m_dp.pszFileName, CHAR, strlen (szPath)+1);
01514 strcpy (m_dp.pszFileName, szPath);
01515
01516 Event (DE_EXTERROR, DMEE_FILEUPDATED);
01517
01518 return TRUE;
01519 }
01520
01521 BOOL fsDownloadMgr::ReserveDiskSpace()
01522 {
01523
01524 if (FALSE == m_dp.bReserveDiskSpace || m_dldr.GetLDFileSize () == _UI64_MAX)
01525 return TRUE;
01526
01527 if (FALSE == fsSetFilePointer (m_hOutFile, m_dldr.GetLDFileSize (), FILE_BEGIN))
01528 return FALSE;
01529
01530 if (FALSE == SetEndOfFile (m_hOutFile))
01531 return FALSE;
01532
01533 if (m_dldr.GetNumberOfSections () == 1 && m_dldr.GetLDFileSize () > 100 * 1024 * 1024)
01534 {
01535 m_bDontCreateNewSections = TRUE;
01536 InterlockedIncrement (&m_iThread);
01537 DWORD dw;
01538 CloseHandle (
01539 CreateThread (NULL, 0, _threadReserveDiskSpace, this, 0, &dw));
01540 }
01541
01542 return TRUE;
01543 }
01544
01545 void fsDownloadMgr::ApplyAdditionalExt()
01546 {
01547 CHAR szFile [MY_MAX_PATH];
01548 int fl = strlen (m_dp.pszFileName);
01549 int el = strlen (m_dp.pszAdditionalExt);
01550
01551 if (el == 0)
01552 return;
01553
01554 if (fl > el)
01555 {
01556
01557 if (stricmp (m_dp.pszFileName + fl - el, m_dp.pszAdditionalExt) == 0 &&
01558 m_dp.pszFileName [fl - el - 1] == '.' )
01559 return;
01560
01561 if (fl + el >= MY_MAX_PATH)
01562 return;
01563 }
01564
01565 strcpy (szFile, m_dp.pszFileName);
01566 strcat (szFile, ".");
01567 strcat (szFile, m_dp.pszAdditionalExt);
01568
01569 SAFE_DELETE_ARRAY (m_dp.pszFileName);
01570 fsnew (m_dp.pszFileName, CHAR, strlen (szFile) + 1);
01571 strcpy (m_dp.pszFileName, szFile);
01572 }
01573
01574 DWORD fsDownloadMgr::OnSCR()
01575 {
01576 return ProcessSCR (m_dp.enSCR, TRUE);
01577 }
01578
01579 DWORD fsDownloadMgr::ProcessSCR(fsSizeChangeReaction scr, BOOL bFirstCall)
01580 {
01581
01582 if (bFirstCall)
01583 {
01584 if (FALSE == OpenFile ())
01585 {
01586 DWORD dwLastError = GetLastError ();
01587 Event (LS (L_FAILEDTOOPEN), EDT_RESPONSE_E);
01588 DescribeAPIError (&dwLastError);
01589 m_state |= DS_NEEDSTOP;
01590 return SCR_STOP;
01591 }
01592 Event (LS (L_FILESIZEWASCHANGED), EDT_WARNING);
01593 }
01594
01595 switch (scr)
01596 {
01597 case SCR_ASKUSER:
01598 {
01599 #ifndef FDM_DLDR__RAWCODEONLY
01600 CSCRDlg dlg;
01601 dlg.m_dnp = GetDNP ();
01602 _DlgMgr.OnDoModal (&dlg);
01603 dlg.DoModal ();
01604 _DlgMgr.OnEndDialog (&dlg);
01605 if (dlg.m_bDontAskAgain)
01606 {
01607 m_dp.enSCR = dlg.m_enSCR;
01608 _App.SizeChangeReaction (dlg.m_enSCR);
01609 }
01610
01611 return ProcessSCR (dlg.m_enSCR, FALSE);
01612 #endif
01613
01614 }
01615
01616 case SCR_RESTART:
01617 Event (LS (L_RESTARTINGDLD), EDT_WARNING);
01618 SetFilePointer (m_hOutFile, 0, NULL, FILE_BEGIN);
01619 SetEndOfFile (m_hOutFile);
01620 break;
01621
01622 case SCR_ADJUSTFORNEWSIZE:
01623 {
01624 Event (LS (L_ADJFORNEWSIZE), EDT_WARNING);
01625
01626 UINT64 uNewSize = m_dldr.GetSSFileSize ();
01627 UINT64 uOldSize = GetFileSize (m_hOutFile, NULL);
01628
01629 if (uOldSize > uNewSize)
01630 {
01631 fsSetFilePointer (m_hOutFile, uNewSize, FILE_BEGIN);
01632 SetEndOfFile (m_hOutFile);
01633 }
01634 }
01635 break;
01636
01637 case SCR_STOP:
01638 m_state |= DS_NEEDSTOP;
01639 Event (DE_EXTERROR, DMEE_USERSTOP);
01640 break;
01641
01642 default:
01643 ASSERT (5!=5);
01644 }
01645
01646 return scr;
01647 }
01648
01649 void fsDownloadMgr::DescribeAPIError(DWORD* pdwLastError)
01650 {
01651 CHAR szErr [1000];
01652 fsErrorToStr (szErr, sizeof (szErr), pdwLastError);
01653 Event (szErr, EDT_RESPONSE_E);
01654 }
01655
01656 void fsDownloadMgr::OnDone()
01657 {
01658 CloseFile ();
01659 RemoveHiddenAttribute ();
01660
01661
01662 int fl = strlen (m_dp.pszFileName);
01663 int el = strlen (m_dp.pszAdditionalExt);
01664
01665 if (el == 0 || el >= fl-1)
01666 {
01667 if (m_dp.dwFlags & DPF_APPENDCOMMENTTOFILENAME)
01668 AppendCommentToFileName (TRUE);
01669 return;
01670 }
01671
01672 if (fsStrNCmpNC (m_dp.pszFileName +fl - el, m_dp.pszAdditionalExt, el))
01673 {
01674 if (m_dp.dwFlags & DPF_APPENDCOMMENTTOFILENAME)
01675 AppendCommentToFileName (TRUE);
01676 return;
01677 }
01678
01679 CHAR szFileNameFrom [MY_MAX_PATH];
01680 strcpy (szFileNameFrom, m_dp.pszFileName);
01681
01682 m_dp.pszFileName [fl-el-1] = 0;
01683
01684 if (m_dp.dwFlags & DPF_APPENDCOMMENTTOFILENAME)
01685 AppendCommentToFileName (FALSE);
01686
01687 CheckDstFileExists ();
01688
01689 if (DWORD (-1) != GetFileAttributes (m_dp.pszFileName))
01690 ::DeleteFile (m_dp.pszFileName);
01691 if (FALSE == ::MoveFile (szFileNameFrom, m_dp.pszFileName))
01692 {
01693 DWORD dwLastError = GetLastError ();
01694 Event (LS (L_CANTRENAMEBACK), EDT_RESPONSE_E);
01695 DescribeAPIError (&dwLastError);
01696 lstrcpy (m_dp.pszFileName, szFileNameFrom);
01697 }
01698 }
01699
01700 BOOL fsDownloadMgr::DeleteFile()
01701 {
01702 if (m_dwDownloadFileFlags & DFF_NEED_INIT_FILE)
01703 return TRUE;
01704
01705 StopDownloading ();
01706
01707 CloseFile ();
01708
01709 if (GetFileAttributes (m_dp.pszFileName) != DWORD (-1))
01710 {
01711 fsString str = m_dp.pszFileName;
01712 str += ".dsc.txt";
01713 ::DeleteFile (str);
01714 return ::DeleteFile (m_dp.pszFileName);
01715 }
01716 else
01717 return TRUE;
01718 }
01719
01720 void fsDownloadMgr::CloseFile()
01721 {
01722 if (m_hOutFile != INVALID_HANDLE_VALUE)
01723 {
01724 m_dldr.SetOutputFile (INVALID_HANDLE_VALUE);
01725 CloseHandle (m_hOutFile);
01726 m_hOutFile = INVALID_HANDLE_VALUE;
01727 }
01728 }
01729
01730 fsInternetResult fsDownloadMgr::GetLastError()
01731 {
01732 return m_lastError;
01733 }
01734
01735 BOOL fsDownloadMgr::InitFile(BOOL bCreateOnDisk, LPCSTR pszSetExt)
01736 {
01737 CString strFileName;
01738
01739 InitFile_ProcessMacroses ();
01740
01741
01742 if (FALSE == BuildFileName (pszSetExt))
01743 {
01744 Event (LS (L_FILENAMETOOLONG), EDT_RESPONSE_E);
01745 m_state |= DS_NEEDSTOP;
01746 m_bFatalError = TRUE;
01747 return FALSE;
01748 }
01749
01750 ApplyAdditionalExt ();
01751
01752 if (!fsBuildPathToFile (m_dp.pszFileName))
01753 goto _lErr;
01754
01755 if (DWORD (-1) != GetFileAttributes (m_dp.pszFileName))
01756 {
01757 fsAlreadyExistReaction enAER = m_dp.enAER;
01758
01759 BOOL bRet = ApplyAER (enAER);
01760
01761 if (bRet == FALSE)
01762 goto _lErr;
01763 else if (bRet == BOOL (-1))
01764 return FALSE;
01765 }
01766
01767 if (bCreateOnDisk)
01768 {
01769 HANDLE hFile = CreateFile (m_dp.pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
01770 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
01771
01772 if (hFile == INVALID_HANDLE_VALUE)
01773 goto _lErr;
01774
01775 SetFileTime (hFile);
01776
01777 CloseHandle (hFile);
01778 }
01779
01780 m_dwDownloadFileFlags &= ~DFF_NEED_INIT_FILE;
01781
01782 return TRUE;
01783
01784 _lErr:
01785 DescribeAPIError ();
01786 m_bFatalError = TRUE;
01787 m_state |= DS_NEEDSTOP;
01788 return FALSE;
01789 }
01790
01791 BOOL fsDownloadMgr::IsFileInit()
01792 {
01793 return (m_dwDownloadFileFlags & DFF_NEED_INIT_FILE) == 0;
01794 }
01795
01796 BOOL fsDownloadMgr::IsSectionCanBeAdded()
01797 {
01798 if (m_dldr.IsHavingError ())
01799 return FALSE;
01800
01801 if (m_state & DS_NEEDSTOP || (m_state & DS_DOWNLOADING == 0))
01802 return FALSE;
01803
01804 if (m_dldr.IsAllSectionsOk () == FALSE)
01805 return FALSE;
01806
01807 if (UINT (m_dldr.GetNumberOfSections () - m_dldr.GetDoneSectionCount ()) < m_dp.uMaxSections)
01808 return TRUE;
01809
01810 return FALSE;
01811 }
01812
01813 fsInternetResult fsDownloadMgr::RestartDownloading()
01814 {
01815 fsInternetResult ir = SetToRestartState ();
01816
01817 if (ir != IR_SUCCESS)
01818 return ir;
01819
01820 return StartDownloading ();
01821 }
01822
01823 void fsDownloadMgr::StopSection()
01824 {
01825 if (IsRunning () == FALSE)
01826 return;
01827
01828 if (m_dldr.GetRunningSectionCount () == 1)
01829 StopDownloading ();
01830 else
01831 m_dldr.StopSection ();
01832 }
01833
01834 void fsDownloadMgr::CreateOneMoreSection()
01835 {
01836 if (m_dldr.IsSectionCreatingNow () == FALSE)
01837 m_state |= DS_NEEDADDSECTION2;
01838 }
01839
01840 fsInternetResult fsDownloadMgr::QuerySize(BOOL bCheckPoss)
01841 {
01842 if (bCheckPoss)
01843 if (IsRunning () || IsQueringSize ())
01844 return IR_S_FALSE;
01845
01846 fsInternetResult ir;
01847
01848 m_state |= DS_QUERINGSIZE;
01849
01850 ir = CreateInternetSession ();
01851 if (ir != IR_SUCCESS)
01852 {
01853 m_state &= ~DS_QUERINGSIZE;
01854 return ir;
01855 }
01856
01857 ApplyProperties ();
01858
01859 ir = m_dldr.QuerySize ();
01860
01861 m_state &= ~DS_QUERINGSIZE;
01862 return ir;
01863 }
01864
01865 BOOL fsDownloadMgr::IsQueringSize()
01866 {
01867 return m_state & DS_QUERINGSIZE;
01868 }
01869
01870 void fsDownloadMgr::QuerySize2()
01871 {
01872 if (IsRunning () || IsQueringSize ())
01873 return;
01874
01875 m_state |= DS_QUERINGSIZE;
01876
01877 DWORD dw;
01878 InterlockedIncrement (&m_iThread);
01879 CloseHandle (CreateThread (NULL, 0, _threadQSize, this, 0, &dw));
01880 }
01881
01882 DWORD WINAPI fsDownloadMgr::_threadQSize(LPVOID lp)
01883 {
01884 fsDownloadMgr *pThis = (fsDownloadMgr*) lp;
01885 try{
01886 pThis->Event (LS (L_QUERINGSIZE));
01887 fsInternetResult ir = pThis->QuerySize (FALSE);
01888 if (ir != IR_SUCCESS)
01889 {
01890 char szErr [10000];
01891 fsIRToStr (ir, szErr, sizeof (szErr));
01892 pThis->Event (szErr, EDT_RESPONSE_E);
01893 }
01894 else
01895 pThis->Event (LS (L_DONE), EDT_DONE);
01896 pThis->Event (DE_EXTERROR, DMEE_FILEUPDATED);
01897 }catch (...){}
01898 InterlockedDecrement (&pThis->m_iThread);
01899 return 0;
01900 }
01901
01902 void fsDownloadMgr::StopQuering()
01903 {
01904 if (IsQueringSize ())
01905 {
01906 m_dldr.StopDownloading ();
01907 }
01908 }
01909
01910 BOOL fsDownloadMgr::IsCantStart()
01911 {
01912 return m_bCantStart;
01913 }
01914
01915 void fsDownloadMgr::CloneSettings(fsDownloadMgr *src)
01916 {
01917 fsDownload_Properties *dp = src->GetDP ();
01918 fsDownload_NetworkProperties *dnp = src->GetDNP ();
01919 fsDownload_NetworkProperties *mydnp = GetDNP ();
01920
01921 CopyMemory (m_dp.aEP, dp->aEP, sizeof (m_dp.aEP));
01922 m_dp.dwFlags = dp->dwFlags;
01923 m_dp.bIgnoreRestrictions = dp->bIgnoreRestrictions;
01924 m_dp.bReserveDiskSpace = dp->bReserveDiskSpace;
01925 m_dp.bRestartSpeedLow = dp->bRestartSpeedLow;
01926 m_dp.enAER = dp->enAER;
01927 m_dp.enSCR = dp->enSCR;
01928
01929 SAFE_DELETE_ARRAY (m_dp.pszAdditionalExt);
01930 m_dp.pszAdditionalExt = new char [strlen (dp->pszAdditionalExt) + 1];
01931 strcpy (m_dp.pszAdditionalExt, dp->pszAdditionalExt);
01932
01933 SAFE_DELETE_ARRAY (m_dp.pszCreateExt);
01934 m_dp.pszCreateExt = new char [strlen (dp->pszCreateExt) + 1];
01935 strcpy (m_dp.pszCreateExt, dp->pszCreateExt);
01936
01937 if (m_dp.pszFileName == NULL || *m_dp.pszFileName == 0 || m_dp.pszFileName [strlen (m_dp.pszFileName) - 1] == '\\' || m_dp.pszFileName [strlen (m_dp.pszFileName) - 1] == '/')
01938 {
01939 if (dp->pszFileName)
01940 {
01941 SAFE_DELETE_ARRAY (m_dp.pszFileName);
01942 m_dp.pszFileName = new char [strlen (dp->pszFileName) + 1];
01943 strcpy (m_dp.pszFileName, dp->pszFileName);
01944 }
01945 }
01946 m_dp.uMaxAttempts = dp->uMaxAttempts;
01947 m_dp.uMaxSections = dp->uMaxSections;
01948 m_dp.uRetriesTime = dp->uRetriesTime;
01949 m_dp.uSectionMinSize = dp->uSectionMinSize;
01950 m_dp.uTimeout = dp->uTimeout;
01951 m_dp.uTrafficRestriction = dp->uTrafficRestriction;
01952
01953 mydnp->dwFtpFlags = dnp->dwFtpFlags;
01954 mydnp->bUseCookie = dnp->bUseCookie;
01955 mydnp->bUseHttp11 = dnp->bUseHttp11;
01956 mydnp->enAccType = dnp->enAccType;
01957 mydnp->enFtpTransferType = dnp->enFtpTransferType;
01958
01959 SAFE_DELETE_ARRAY (mydnp->pszAgent);
01960 mydnp->pszAgent = new char [strlen (dnp->pszAgent) + 1];
01961 strcpy (mydnp->pszAgent, dnp->pszAgent);
01962
01963 SAFE_DELETE_ARRAY (mydnp->pszASCIIExts);
01964 mydnp->pszASCIIExts = new char [strlen (dnp->pszASCIIExts) + 1];
01965 strcpy (mydnp->pszASCIIExts, dnp->pszASCIIExts);
01966
01967 SAFE_DELETE_ARRAY (mydnp->pszReferer);
01968 mydnp->pszReferer = new char [strlen (dnp->pszReferer) + 1];
01969 strcpy (mydnp->pszReferer, dnp->pszReferer);
01970
01971 SAFE_DELETE_ARRAY (mydnp->pszUserName);
01972 mydnp->pszUserName = new char [strlen (dnp->pszUserName) + 1];
01973 strcpy (mydnp->pszUserName, dnp->pszUserName);
01974
01975 SAFE_DELETE_ARRAY (mydnp->pszPassword);
01976 mydnp->pszPassword = new char [strlen (dnp->pszPassword) + 1];
01977 strcpy (mydnp->pszPassword, dnp->pszPassword);
01978 }
01979
01980 void fsDownloadMgr::Set_MirrRecalcSpeedTime(UINT u)
01981 {
01982 m_uMirrRecalcSpeedTime = u;
01983 }
01984
01985 fsInternetResult fsDownloadMgr::FindMirrors()
01986 {
01987 fsInternetResult ir = CreateInternetSession ();
01988 if (ir != IR_SUCCESS)
01989 {
01990 m_state &= ~DS_QUERINGSIZE;
01991 return ir;
01992 }
01993
01994 ApplyProperties ();
01995
01996 return m_dldr.FindMirrors ();
01997 }
01998
01999 fsInternetResult fsDownloadMgr::SetToRestartState()
02000 {
02001 if (IsRunning ())
02002 return IR_S_FALSE;
02003
02004 if (IsFileInit ())
02005 {
02006 if (m_dp.enAER != AER_RENAME_2)
02007 DeleteFile ();
02008 else
02009 m_bRename_CheckIfRenamed = TRUE;
02010 m_dwDownloadFileFlags |= DFF_NEED_INIT_FILE;
02011 }
02012
02013 m_dldr.DeleteAllSections ();
02014
02015 return IR_SUCCESS;
02016 }
02017
02018 void fsDownloadMgr::CheckMirrSpeedRecalcRequired()
02019 {
02020 if (m_uMirrRecalcSpeedTime == 0)
02021 return;
02022
02023 fsTicksMgr tikNow;
02024
02025 tikNow.Now ();
02026
02027 if (tikNow - m_tikLastMirrMeasureTime > m_uMirrRecalcSpeedTime*60*1000)
02028 {
02029 m_tikLastMirrMeasureTime.Now ();
02030 DWORD dwThread;
02031 InterlockedIncrement (&m_iThread);
02032 CloseHandle (CreateThread (NULL, 0, _threadCalcMirrSpeed, this, 0, &dwThread));
02033 }
02034 }
02035
02036 DWORD WINAPI fsDownloadMgr::_threadCalcMirrSpeed(LPVOID lp)
02037 {
02038 fsDownloadMgr* pThis = (fsDownloadMgr*) lp;
02039
02040 try {
02041
02042 pThis->MeasureMirrorsSpeed ();
02043
02044 } catch (...) {}
02045
02046 InterlockedDecrement (&pThis->m_iThread);
02047
02048 return 0;
02049 }
02050
02051 void fsDownloadMgr::MeasureMirrorsSpeed()
02052 {
02053 Event (LS (L_CALCULATINGMIRRORSSPEED));
02054 m_dldr.MeasureMirrorsSpeed ();
02055 m_tikLastMirrMeasureTime.Now ();
02056 Event (LS (L_MIRRORSSPEEDWASMEASURED), EDT_RESPONSE_S);
02057 }
02058
02059 BOOL fsDownloadMgr::OnNeedFile_FinalInit()
02060 {
02061 SetFileTime (m_hOutFile);
02062
02063
02064 if (!ReserveDiskSpace ())
02065 {
02066 if (m_state & DS_NEEDSTOP)
02067 return FALSE;
02068 goto _lErr;
02069 }
02070
02071 return TRUE;
02072
02073 _lErr:
02074 DescribeAPIError ();
02075 m_state |= DS_NEEDSTOP;
02076 Event (DE_EXTERROR, DMEE_FATALERROR);
02077 m_bFatalError = TRUE;
02078 return FALSE;
02079 }
02080
02081 void fsDownloadMgr::RemoveHiddenAttribute()
02082 {
02083 if (m_dp.dwFlags & DPF_USEHIDDENATTRIB)
02084 {
02085 DWORD dw = GetFileAttributes (m_dp.pszFileName);
02086 dw &= ~ FILE_ATTRIBUTE_HIDDEN;
02087 SetFileAttributes (m_dp.pszFileName, dw);
02088 }
02089 }
02090
02091 void fsDownloadMgr::CheckDstFileExists()
02092 {
02093
02094 if (GetFileAttributes (m_dp.pszFileName) != DWORD (-1))
02095 {
02096 fsAlreadyExistReaction enAER = m_dp.enAER;
02097
02098 if (enAER == AER_ASKUSER)
02099 {
02100 #ifndef FDM_DLDR__RAWCODEONLY
02101 CAERDlg dlg;
02102
02103 dlg.m_pszFile = m_dp.pszFileName;
02104 dlg.DisableStopAndResume ();
02105 _DlgMgr.OnDoModal (&dlg);
02106 dlg.DoModal ();
02107 _DlgMgr.OnEndDialog (&dlg);
02108
02109 if (dlg.m_bDontAskAgain)
02110 {
02111 m_dp.enAER = dlg.m_enAER;
02112 _App.AlreadyExistReaction (dlg.m_enAER);
02113 }
02114
02115 enAER = dlg.m_enAER;
02116 #else
02117 enAER = AER_REWRITE;
02118 #endif
02119 }
02120
02121 switch (enAER)
02122 {
02123 case AER_REWRITE:
02124 Event (LS (L_REWRITINGIT), EDT_WARNING);
02125 if (FALSE == ::DeleteFile (m_dp.pszFileName))
02126 {
02127 DWORD dwLastError = GetLastError ();
02128 Event (LS (L_CANTREWRITE), EDT_RESPONSE_E);
02129 DescribeAPIError (&dwLastError);
02130 Event (LS (L_WILLBERENAMED), EDT_WARNING);
02131 RenameFile (FALSE);
02132 }
02133 break;
02134
02135 case AER_STOP:
02136 case AER_RESUME:
02137 case AER_RENAME:
02138 case AER_RENAME_2:
02139 RenameFile ();
02140 break;
02141 }
02142 }
02143 }
02144
02145 void fsDownloadMgr::AppendCommentToFileName(BOOL bMoveFile)
02146 {
02147 if (m_dld == NULL || m_dld->strComment.GetLength () == 0)
02148 return;
02149
02150 char szOldName [MY_MAX_PATH];
02151 strcpy (szOldName, m_dp.pszFileName);
02152
02153 LPCSTR pszExt = strrchr (szOldName, '.');
02154
02155 delete [] m_dp.pszFileName;
02156
02157 m_dp.pszFileName = new char [strlen (szOldName) + m_dld->strComment.GetLength () + 10 + 1];
02158
02159 strcpy (m_dp.pszFileName, szOldName);
02160 if (pszExt)
02161 {
02162 strcpy (m_dp.pszFileName + (pszExt - szOldName), " (");
02163 strcat (m_dp.pszFileName, m_dld->strComment);
02164 strcat (m_dp.pszFileName, ")");
02165 strcat (m_dp.pszFileName, pszExt);
02166 }
02167
02168 if (bMoveFile)
02169 {
02170 CheckDstFileExists ();
02171
02172 if (FALSE == ::MoveFile (szOldName, m_dp.pszFileName))
02173 {
02174 DWORD dwLastError = GetLastError ();
02175 Event (LS (L_CANTRENAMEBACK), EDT_RESPONSE_E);
02176 DescribeAPIError (&dwLastError);
02177 }
02178 }
02179 }
02180
02181 void fsDownloadMgr::set_Download(fsDownload *dld)
02182 {
02183 m_dld = dld;
02184 }
02185
02186 BOOL fsDownloadMgr::is_GlobalOffline()
02187 {
02188 DWORD dwState = 0;
02189 DWORD dwSize = sizeof(DWORD);
02190 BOOL bRet = FALSE;
02191
02192 if (InternetQueryOption (NULL,
02193 INTERNET_OPTION_CONNECTED_STATE, &dwState, &dwSize))
02194 {
02195 if (dwState & INTERNET_STATE_DISCONNECTED_BY_USER)
02196 bRet = TRUE;
02197 }
02198
02199 return bRet;
02200 }
02201
02202 void fsDownloadMgr::set_GlobalOffline(BOOL bOffline)
02203 {
02204 INTERNET_CONNECTED_INFO ci;
02205 ZeroMemory (&ci, sizeof(ci));
02206
02207 if (bOffline)
02208 {
02209 ci.dwConnectedState = INTERNET_STATE_DISCONNECTED_BY_USER;
02210 ci.dwFlags = ISO_FORCE_DISCONNECTED;
02211 }
02212 else
02213 {
02214 ci.dwConnectedState = INTERNET_STATE_CONNECTED;
02215 }
02216
02217 InternetSetOption (NULL,
02218 INTERNET_OPTION_CONNECTED_STATE, &ci, sizeof(ci));
02219 }
02220
02221 void fsDownloadMgr::SetFileTime(HANDLE hFile)
02222 {
02223 if ((m_dp.dwFlags & DPF_RETRDATEFROMSERVER) == 0)
02224 return;
02225
02226 FILETIME time = m_dldr.get_FileDate ();
02227 if (time.dwHighDateTime != 0 || time.dwLowDateTime != 0)
02228 ::SetFileTime (hFile, &time, NULL, NULL);
02229 }
02230
02231 BOOL fsDownloadMgr::MoveFile(LPCSTR pszNewFileName)
02232 {
02233 if (IsRunning ())
02234 {
02235 SetLastError (0);
02236 return FALSE;
02237 }
02238
02239 BOOL bOk = TRUE;
02240
02241
02242 if (IsFileInit ())
02243 {
02244 fsBuildPathToFile (pszNewFileName);
02245
02246 if (GetFileAttributes (m_dp.pszFileName) != DWORD (-1))
02247 bOk = ::MoveFile (m_dp.pszFileName, pszNewFileName);
02248 else
02249 bOk = TRUE;
02250 }
02251
02252 if (bOk == FALSE)
02253 return FALSE;
02254
02255 SAFE_DELETE_ARRAY (m_dp.pszFileName);
02256 fsnew (m_dp.pszFileName, char, lstrlen (pszNewFileName) + 1);
02257 lstrcpy (m_dp.pszFileName, pszNewFileName);
02258
02259 return TRUE;
02260 }
02261
02262 BOOL fsDownloadMgr::MoveToFolder(LPCSTR pszPath)
02263 {
02264 CString str = pszPath;
02265 ProcessFilePathMacroses (str);
02266
02267 char szFile [MY_MAX_PATH] = "";
02268 fsGetFileName (m_dp.pszFileName, szFile);
02269
02270 char szNewFile [MY_MAX_PATH];
02271 lstrcpy (szNewFile, str);
02272
02273 if (szNewFile [lstrlen (szNewFile) - 1] != '\\' &&
02274 szNewFile [lstrlen (szNewFile) - 1] != '/')
02275 lstrcat (szNewFile, "\\");
02276
02277 lstrcat (szNewFile, szFile);
02278
02279 return MoveFile (szNewFile);
02280 }
02281
02282 fsString fsDownloadMgr::get_URL()
02283 {
02284 fsURL url;
02285 char szUrl [10000] = "";
02286 DWORD dwLen = sizeof (szUrl);
02287
02288 fsDownload_NetworkProperties* dnp = GetDNP ();
02289
02290 url.Create (fsNPToScheme (dnp->enProtocol), dnp->pszServerName, dnp->uServerPort,
02291 NULL, NULL, dnp->pszPathName, szUrl, &dwLen);
02292
02293 return szUrl;
02294 }
02295
02296 #ifndef FDM_DLDR__RAWCODEONLY
02297 BOOL fsDownloadMgr::CheckIfMalicious()
02298 {
02299 if (m_dld == NULL || (m_dld->dwFlags & DLD_MALICIOUS_DISABLE_CHECK) ||
02300 _App.Community_CheckIfMalBeforeDlding () == FALSE)
02301 return TRUE;
02302
02303 if (m_dld->dwFlags & (DLD_MALICIOUS_YES | DLD_MALICIOUS_NO))
02304 return TRUE;
02305
02306 Event (LS (L_CHECKINGIFDLDISMAL), EDT_INQUIRY);
02307
02308 vmsMaliciousDownloadChecker mdc;
02309 m_mdc = &mdc;
02310 fsInternetResult ir = mdc.Check (get_URL ());
02311 m_mdc = NULL;
02312
02313 if (ir != IR_SUCCESS)
02314 {
02315 char szErr [1000];
02316 fsIRToStr (ir, szErr, sizeof (szErr));
02317 Event (szErr, EDT_RESPONSE_E);
02318 return TRUE;
02319 }
02320
02321 int nPerc = MulDiv (mdc.get_MaliciousOpinionCount (), 100, mdc.get_OpinionTotalCount ());
02322 if (nPerc < _App.Community_MalReportsMinPerc ())
02323 {
02324 m_dld->dwFlags |= DLD_MALICIOUS_NO;
02325 Event (LS (L_DLD_NO_USERS_MAL_REPS), EDT_RESPONSE_S);
02326 return TRUE;
02327 }
02328
02329 m_dld->dwFlags |= DLD_MALICIOUS_YES;
02330 Event (LS (L_THTREAREMALOPINIONS2), EDT_WARNING);
02331
02332 CString str;
02333 str.Format (LS (L_THEREAREMALOPINIONS), mdc.get_MaliciousOpinionCount (),
02334 mdc.get_OpinionTotalCount (), 2, mdc.get_AverageRating ());
02335 UINT nRet = MyMessageBox (NULL, str, LS (L_WARNING), NULL, IDI_WARNING,
02336 LS (L_YES), LS (L_IGNORE), LS (L_STOP));
02337
02338 bool bNeedStop = false;
02339
02340 if (nRet == IDC_BTN3)
02341 bNeedStop = true;
02342 else if (nRet == IDC_BTN1)
02343 {
02344 m_dld->AddRef ();
02345 if (FALSE == _pwndDownloads->SendMessage (WM_DLD_SHOWOPINIONS, 0, (LPARAM)(fsDownload*)m_dld))
02346 bNeedStop = true;
02347 }
02348
02349 if (bNeedStop)
02350 {
02351 Event (LS (L_STOPPED), EDT_RESPONSE_S);
02352 m_dld->dwFlags &= ~DLD_MALICIOUS_YES;
02353 return FALSE;
02354 }
02355
02356 return TRUE;
02357 }
02358 #endif
02359
02360 void fsDownloadMgr::Reset()
02361 {
02362 ASSERT (IsRunning () == FALSE);
02363 if (IsRunning ())
02364 return;
02365
02366 m_dldr.RemoveAllMirrors ();
02367 m_dldr.ResetSections ();
02368
02369 m_dwDownloadFileFlags |= DFF_NEED_INIT_FILE;
02370 }
02371
02372 void fsDownloadMgr::InitFile_ProcessMacroses()
02373 {
02374 CString str = m_dp.pszFileName;
02375
02376 ProcessFilePathMacroses (str);
02377
02378 delete [] m_dp.pszFileName;
02379 m_dp.pszFileName = new char [str.GetLength () + 1];
02380 lstrcpy (m_dp.pszFileName, str);
02381 }
02382
02383 void fsDownloadMgr::ProcessFilePathMacroses(CString &str)
02384 {
02385 #ifndef FDM_DLDR__RAWCODEONLY
02386
02387 if (str.Find ('%', 0) == -1)
02388 return;
02389
02390 if (str.Find ("%sdrive%") != -1)
02391 {
02392 str.Replace ("%sdrive%", CString (vmsGetExeDriveLetter ()) + ":");
02393 m_dwDownloadFileFlags |= DFF_USE_PORTABLE_DRIVE;
02394 }
02395
02396 str.Replace ("%server%", GetDNP ()->pszServerName);
02397
02398 char szUrlPath [MY_MAX_PATH];
02399 fsGetPath (GetDNP ()->pszPathName, szUrlPath);
02400 if (lstrlen (szUrlPath) > 1)
02401 str.Replace ("%path_on_server%", szUrlPath);
02402 else
02403 str.Replace ("%path_on_server%", "");
02404 str.Replace ("/", "\\");
02405 str.Replace ("\\\\", "\\");
02406
02407 SYSTEMTIME st;
02408 GetLocalTime (&st);
02409
02410 str.Replace ("%date%", "%year%-%month%-%day%");
02411
02412 CString strY, strM, strD;
02413 strY.Format ("%04d", (int)st.wYear);
02414 strM.Format ("%02d", (int)st.wMonth);
02415 strD.Format ("%02d", (int)st.wDay);
02416
02417 str.Replace ("%year%", strY);
02418 str.Replace ("%month%", strM);
02419 str.Replace ("%day%", strD);
02420
02421 #endif
02422 }
02423
02424 void fsDownloadMgr::DoRapidshareSupport()
02425 {
02426 if (m_bRSsupportDone)
02427 return;
02428
02429 fsDownload_NetworkProperties *dnp = GetDNP ();
02430
02431 if (dnp->pszUserName && dnp->pszPassword && *dnp->pszUserName && *dnp->pszPassword)
02432 {
02433 if (strnicmp (dnp->pszServerName, "rapidshare.", 11) == 0 ||
02434 strnicmp (dnp->pszServerName, "www.rapidshare.", 15) == 0)
02435 {
02436 char szCookies [1000];
02437 lstrcpy (szCookies, "user=");
02438 lstrcat (szCookies, dnp->pszUserName);
02439 lstrcat (szCookies, "-");
02440 LPCSTR psz = dnp->pszPassword;
02441 while (*psz)
02442 sprintf (szCookies + lstrlen (szCookies), "%%%x", *psz++);
02443
02444 if (dnp->pszCookies == NULL || *dnp->pszCookies == 0)
02445 {
02446 SAFE_DELETE_ARRAY (dnp->pszCookies);
02447 dnp->pszCookies = new char [lstrlen (szCookies) + 1];
02448 *dnp->pszCookies = 0;
02449 }
02450 else
02451 {
02452 if (strstr (dnp->pszCookies, szCookies) != NULL)
02453 {
02454 m_bRSsupportDone = true;
02455 return;
02456 }
02457
02458 char *psz = new char [lstrlen (dnp->pszCookies) + lstrlen (szCookies) + 10];
02459 lstrcpy (psz, dnp->pszCookies);
02460 if (psz [lstrlen (psz) - 1] != ';')
02461 lstrcat (psz, ";");
02462 delete [] dnp->pszCookies;
02463 dnp->pszCookies = psz;
02464 }
02465
02466 lstrcat (dnp->pszCookies, szCookies);
02467
02468 dnp->dwFlags |= DNPF_IMMEDIATELY_SEND_AUTH_AS_BASIC;
02469 }
02470 }
02471 }
02472
02473 int fsDownloadMgr::get_ReservingDiskSpaceProgress()
02474 {
02475 return 0;
02476 }
02477
02478 fsDownloadState fsDownloadMgr::get_State()
02479 {
02480 return m_state;
02481 }
02482
02483 BOOL fsDownloadMgr::HasActivity()
02484 {
02485 return m_iThread != 0;
02486 }
02487
02488 DWORD WINAPI fsDownloadMgr::_threadReserveDiskSpace(LPVOID lp)
02489 {
02490 fsDownloadMgr *pthis = (fsDownloadMgr*)lp;
02491
02492 ASSERT (pthis->m_dldr.GetNumberOfSections () == 1);
02493 ASSERT (pthis->m_dldr.GetLDFileSize () != _UI64_MAX);
02494
02495 UINT64 uStartPos = pthis->m_dldr.GetDownloadedBytesCount () + 100 * 1024 * 1024;
02496
02497 UINT64 uHundredthPart = pthis->m_dldr.GetLDFileSize () / 100;
02498
02499 for (UINT64 uCurPos = uStartPos; uCurPos < pthis->m_dldr.GetLDFileSize (); uCurPos += uHundredthPart)
02500 {
02501 UINT64 uSectLastDownloadPos = pthis->m_dldr.GetDownloadedBytesCount ();
02502
02503 pthis->m_dldr.LockWriteFile (TRUE);
02504
02505 fsSetFilePointer (pthis->m_hOutFile, uCurPos, FILE_BEGIN);
02506
02507 BYTE b = 1; DWORD dw;
02508 if (FALSE == WriteFile (pthis->m_hOutFile, &b, sizeof (b), &dw, NULL))
02509 {
02510 pthis->m_dldr.LockWriteFile (FALSE);
02511 break;
02512 }
02513
02514 pthis->m_dldr.LockWriteFile (FALSE);
02515
02516 if (pthis->m_dldr.GetDownloadedBytesCount () == uSectLastDownloadPos)
02517 {
02518
02519 Sleep (50);
02520 }
02521
02522 if (pthis->m_dldr.IsRunning () == FALSE)
02523 break;
02524 }
02525
02526 pthis->m_bDontCreateNewSections = FALSE;
02527 pthis->m_state |= DS_NEEDADDSECTION;
02528
02529 InterlockedDecrement (&pthis->m_iThread);
02530 return 0;
02531 }