00001
00002
00003
00004
00005
00006 #include "stdafx.h"
00007 #include "FdmApp.h"
00008 #include "fsScheduleMgr.h"
00009 #include "DownloadsWnd.h"
00010 #include "fsPluginMgr.h"
00011 #include "DialDlg.h"
00012 #include "fsRASMgr.h"
00013 #include "ShedulerWnd.h"
00014 #include "WaitForConfirmationDlg.h"
00015 #include "SpiderWnd.h"
00016 #include "MainFrm.h"
00017
00018 extern CSpiderWnd *_pwndSpider;
00019
00020 #ifdef _DEBUG
00021 #undef THIS_FILE
00022 static char THIS_FILE[]=__FILE__;
00023 #define new DEBUG_NEW
00024 #endif
00025
00026 extern CDownloadsWnd *_pwndDownloads;
00027 extern fsPluginMgr _PluginMgr;
00028 extern CShedulerWnd* _pwndScheduler;
00029
00030 fsScheduleMgr::fsScheduleMgr()
00031 {
00032 m_bNeedExit = FALSE;
00033
00034 m_pfnEvents = NULL;
00035 m_pfnEventDesc = NULL;
00036
00037 m_uID = 0;
00038 }
00039
00040 fsScheduleMgr::~fsScheduleMgr()
00041 {
00042 FreeTasks ();
00043 }
00044
00045 DWORD WINAPI fsScheduleMgr::_threadScheduleMgr(LPVOID lp)
00046 {
00047 fsScheduleMgr *pThis = (fsScheduleMgr*) lp;
00048
00049 while (pThis->m_bNeedExit == FALSE)
00050 {
00051 pThis->ManageNotEvents ();
00052 pThis->ManageHalfEvents ();
00053
00054 int iSleep = 1000;
00055 while (iSleep && pThis->m_bNeedExit == FALSE)
00056 {
00057 iSleep -= 200;
00058 Sleep (200);
00059 }
00060 }
00061
00062 LOG ("threadScheduleMgr shutted down" << nl);
00063
00064 pThis->m_bNeedExit = FALSE;
00065
00066 return 0;
00067 }
00068
00069 void fsScheduleMgr::ManageNotEvents()
00070 {
00071 UpdateCurrentTime ();
00072
00073
00074 fs::list <fsSchedule*> vTasks;
00075
00076 for (int i = m_vTasks.size () - 1; i >= 0; i--)
00077 {
00078 fsSchedule *task = m_vTasks [i];
00079
00080 if ((task->dwFlags & SCHEDULE_ENABLED) == 0)
00081 continue;
00082
00083 if (IsTimeBased (task))
00084 {
00085 if (IsNeedToStart (task))
00086 {
00087 if (task->wts.enType == WTS_SHUTDOWN)
00088 vTasks.insert (0, task);
00089 else if (task->wts.enType == WTS_EXIT)
00090 vTasks.add (task);
00091 else
00092 StartTask (task);
00093 }
00094 }
00095 }
00096
00097 for (i = 0; i < vTasks.size (); i++)
00098 StartTask (vTasks [i]);
00099 }
00100
00101 BOOL fsScheduleMgr::IsNeedToStart(fsSchedule *task)
00102 {
00103 SYSTEMTIME time1, time2;
00104
00105 FileTimeToSystemTime (&m_curTime, &time1);
00106 FileTimeToSystemTime (&task->hts.next, &time2);
00107
00108
00109 if (time1.wYear == time2.wYear && time1.wMonth == time2.wMonth &&
00110 time1.wDay == time2.wDay && time1.wHour == time2.wHour &&
00111 time1.wMinute == time2.wMinute)
00112 {
00113
00114 if (CompareFileTime (&task->hts.last, &task->hts.next))
00115 return TRUE;
00116 }
00117
00118 return FALSE;
00119 }
00120
00121 void fsScheduleMgr::StartTask(fsSchedule *task)
00122 {
00123 if ((task->dwFlags & SCHEDULE_ENABLED) == 0)
00124 return;
00125
00126 if (IsTimeBased (task))
00127 {
00128 task->hts.last = task->hts.next;
00129
00130 GetNextTime (task);
00131 }
00132 else
00133 task->hts.last = m_curTime;
00134
00135 if (task->wts.enType == WTS_HANGUP)
00136 {
00137 fsRASMgr mgr;
00138
00139 if (FALSE == mgr.EnumConnections ())
00140 return;
00141
00142 if (mgr.GetConnectionCount () == 0)
00143 return;
00144 }
00145
00146 OnTaskUpdated (task);
00147
00148 if (task->uWaitForConfirmation)
00149 {
00150 CWaitForConfirmationDlg dlg;
00151 CString strMsg;
00152 CString strTask;
00153
00154 strTask = WTSToStr (task);
00155 strMsg.Format (LS (L_STARTIT), strTask);
00156 dlg.Init (strMsg, task->uWaitForConfirmation);
00157
00158 if (_DlgMgr.DoModal (&dlg) != IDOK)
00159 return;
00160 }
00161
00162 Event (task, SME_TASK_STARTED);
00163
00164 switch (task->wts.enType)
00165 {
00166 case WTS_PROGRAM:
00167 LaunchProgram (task);
00168 break;
00169
00170 case WTS_STARTDOWNLOAD:
00171 StartDownloads (task);
00172 break;
00173
00174 case WTS_STOPDOWNLOAD:
00175 StopDownloads (task);
00176 break;
00177
00178 case WTS_STARTALLDOWNLOADS:
00179 Event (LS (L_STARTALLDLDS));
00180 _DldsMgr.StartAllDownloads (TRUE);
00181 break;
00182
00183 case WTS_STOPALLDOWNLOADS:
00184 Event (LS (L_STOPALLDLDS));
00185 _DldsMgr.StopAllDownloads (TRUE);
00186 break;
00187
00188 case WTS_DIAL:
00189 Dial (task);
00190 break;
00191
00192 case WTS_HANGUP:
00193 Hangup (task);
00194 break;
00195
00196 case WTS_CHANGE_TUM:
00197 {
00198 LPCSTR ppszTUM [] = {LS (L_LIGHT), LS (L_MEDIUM), LS (L_HEAVY)};
00199 CString str;
00200 str.Format (LS (L_CHANGINGTUM), ppszTUM [task->wts.enTUM]);
00201 Event (str);
00202 _pwndDownloads->SetTUM (task->wts.enTUM);
00203 }
00204 break;
00205
00206 case WTS_RESTRAINALLDLDS:
00207 {
00208 Event (WTSToStr (task));
00209 BOOL bEn = fsInternetDownloader::is_PauseMode ();
00210 BOOL bShould;
00211 if (task->wts.enRAD == RAD_ENABLE)
00212 bShould = TRUE;
00213 else if (task->wts.enRAD == RAD_DISABLE)
00214 bShould = FALSE;
00215 else
00216 bShould = !bEn;
00217 if (!bEn != !bShould)
00218 fsInternetDownloader::set_PauseMode (bShould);
00219 }
00220 break;
00221
00222 case WTS_EXIT:
00223 _DlgMgr.EndAllDialogs ();
00224 Event (LS (L_EXIT));
00225 AfxGetApp ()->m_pMainWnd->PostMessage (WM_COMMAND, ID_NEED_EXIT);
00226 break;
00227
00228 case WTS_SHUTDOWN:
00229 _DlgMgr.EndAllDialogs ();
00230 Shutdown (task);
00231 break;
00232 }
00233
00234 if (task->dwFlags & SCHEDULE_AUTODEL)
00235 DeleteTask (task);
00236 else if (task->dwFlags & SCHEDULE_AUTODIS)
00237 {
00238 task->dwFlags &= ~ SCHEDULE_ENABLED;
00239 OnTaskUpdated (task);
00240 }
00241 }
00242
00243 BOOL fsScheduleMgr::IsTimeUnknown(FILETIME &time)
00244 {
00245 return time.dwHighDateTime == UINT_MAX && time.dwLowDateTime == UINT_MAX;
00246 }
00247
00248 void fsScheduleMgr::RepairNextTime(fsSchedule *task)
00249 {
00250 SYSTEMTIME time;
00251 SYSTEMTIME time2;
00252
00253 if (IsTimeBased (task) == FALSE || task->hts.enType == HTS_ONCE)
00254 return;
00255
00256 if (CompareFileTime (&m_curTime, &task->hts.next) != 1)
00257 return;
00258
00259 if (CompareFileTime (&task->hts.next, &task->hts.last) == 0)
00260 return;
00261
00262 FileTimeToSystemTime (&m_curTime, &time);
00263 FileTimeToSystemTime (&task->hts.next, &time2);
00264
00265 if (task->hts.enType == HTS_DAILY ||
00266 (task->hts.enType == HTS_CONTINUOUSLY && task->hts.interval >= 24*60) )
00267 {
00268 time.wHour = time2.wHour;
00269 time.wMinute = time2.wMinute;
00270 time.wSecond = time2.wSecond;
00271 }
00272
00273 SystemTimeToFileTime (&time, &task->hts.next);
00274
00275 GetNextTime (task);
00276 }
00277
00278 void fsScheduleMgr::GetNextTime(fsSchedule *task)
00279 {
00280 if (IsTimeBased (task) == FALSE)
00281 return;
00282
00283 ULARGE_INTEGER next;
00284
00285 next.LowPart = task->hts.next.dwLowDateTime;
00286 next.HighPart = task->hts.next.dwHighDateTime;
00287
00288 switch (task->hts.enType)
00289 {
00290 case HTS_DAILY:
00291 {
00292 SYSTEMTIME time;
00293 FileTimeToSystemTime (&m_curTime, &time);
00294
00295 for (int i = time.wDayOfWeek+1; TRUE; i++)
00296 {
00297 next.QuadPart += (ULONGLONG) 24 * 60 * 60 * 10000000;
00298
00299 if (i == 7)
00300 i = 0;
00301
00302 if (task->hts.aWeeklyDays [i])
00303 break;
00304 }
00305 }
00306 break;
00307
00308 case HTS_CONTINUOUSLY:
00309
00310 next.QuadPart += (ULONGLONG) task->hts.interval * 60 * 10000000;
00311 break;
00312 }
00313
00314 task->hts.next.dwLowDateTime = next.LowPart;
00315 task->hts.next.dwHighDateTime = next.HighPart;
00316 }
00317
00318 BOOL fsScheduleMgr::IsTimeBased(fsSchedule *task)
00319 {
00320
00321 return task->hts.enType == HTS_ONCE || task->hts.enType == HTS_DAILY || task->hts.enType == HTS_CONTINUOUSLY;
00322 }
00323
00324 void fsScheduleMgr::CalculateStartTime(fsSchedule *task)
00325 {
00326 if (!IsTimeBased (task) || task->hts.enType == HTS_ONCE)
00327 return;
00328
00329 SYSTEMTIME timeNow, timeStart, time;
00330 GetLocalTime (&timeNow);
00331
00332 timeStart = timeNow;
00333
00334 FileTimeToSystemTime (&task->hts.next, &time);
00335
00336 timeStart.wHour = time.wHour;
00337 timeStart.wMinute = time.wMinute;
00338 timeStart.wSecond = time.wSecond;
00339
00340 SystemTimeToFileTime (&timeStart, &task->hts.next);
00341
00342 switch (task->hts.enType)
00343 {
00344 case HTS_DAILY:
00345 int iStart, i;
00346
00347 if (CompareFileTime (&m_curTime, &task->hts.next) == -1)
00348 iStart = timeStart.wDayOfWeek;
00349 else
00350 {
00351 iStart = timeStart.wDayOfWeek+1;
00352 ((ULARGE_INTEGER*) &task->hts.next)->QuadPart += (ULONGLONG) 24 * 60 * 60 * 10000000;
00353 }
00354
00355 for (i = iStart; TRUE; i++)
00356 {
00357 if (i == 7)
00358 i = 0;
00359
00360 if (task->hts.aWeeklyDays [i])
00361 break;
00362
00363 ((ULARGE_INTEGER*) &task->hts.next)->QuadPart += (ULONGLONG) 24 * 60 * 60 * 10000000;
00364 }
00365 break;
00366
00367 case HTS_CONTINUOUSLY:
00368
00369 if (CompareFileTime (&m_curTime, &task->hts.next) != -1)
00370
00371 ((ULARGE_INTEGER*) &task->hts.next)->QuadPart += (ULONGLONG) 24 * 60 * 60 * 10000000;
00372 break;
00373 }
00374
00375 OnTaskUpdated (task);
00376 }
00377
00378 int fsScheduleMgr::AddTask(fsSchedule *task)
00379 {
00380 task->hts.last.dwHighDateTime = task->hts.last.dwLowDateTime = UINT (-1);
00381 fsSchedule *t = new fsSchedule;
00382 *t = *task;
00383 m_vTasks.add (t);
00384
00385 if (task->wts.enType == WTS_STARTDOWNLOAD)
00386 {
00387 UpdateTaskDownloads (task);
00388 _pwndSpider->UpdateTasksIcons ();
00389 }
00390
00391 return m_vTasks.size () - 1;
00392 }
00393
00394 CString fsScheduleMgr::WTSToStr(fsSchedule *task)
00395 {
00396 CString str;
00397
00398 switch (task->wts.enType)
00399 {
00400 case WTS_PROGRAM:
00401 str = LS (L_START); str += ' ';
00402 str += task->wts.prog.pszName;
00403 break;
00404
00405 case WTS_STARTDOWNLOAD:
00406 str = LS (L_STARTDLDS);
00407 break;
00408
00409 case WTS_STOPDOWNLOAD:
00410 str = LS (L_STOPDLDS);
00411 break;
00412
00413 case WTS_STARTALLDOWNLOADS:
00414 str = LS (L_STARTALLDLDS);
00415 break;
00416
00417 case WTS_STOPALLDOWNLOADS:
00418 str = LS (L_STOPALLDLDS);
00419 break;
00420
00421 case WTS_DIAL:
00422 str = LS (L_DIAL); str += ' ';
00423 str += task->wts.dial.pszConnection;
00424 break;
00425
00426 case WTS_HANGUP:
00427 str += LS (L_HANGUP); str += ' ';
00428 if (task->wts.pszHangupConnection)
00429 {
00430 str += '"';
00431 str += task->wts.pszHangupConnection;
00432 str += '"';
00433 }
00434 else
00435 str += LS (L_ALLCONNS);
00436 break;
00437
00438 case WTS_CHANGE_TUM:
00439 {
00440 LPCSTR pszTum [] = {LS (L_LIGHT), LS (L_MEDIUM), LS (L_HEAVY)};
00441 str = LS (L_CHANGETUMTO); str += ' '; str += pszTum [task->wts.enTUM];
00442 }
00443 break;
00444
00445 case WTS_EXIT:
00446 str = LS (L_EXIT);
00447 break;
00448
00449 case WTS_SHUTDOWN:
00450 {
00451 LPCSTR pszSh [] = {LS (L_SHUTDOWN), LS (L_RESTARTCOMP), LS (L_LOGOFF), LS (L_HIBERNATE), LS (L_STANDBY)};
00452 str = pszSh [task->wts.shutdown.enShutdown];
00453 }
00454 break;
00455
00456 case WTS_RESTRAINALLDLDS:
00457 {
00458 LPCSTR psz [] = {LS (L_ENABLE), LS (L_DISABLE), LS (L_SWITCH)};
00459 str = LS (L_PAUSEALLDOWNLOADS);
00460 str += " ("; str += psz [task->wts.enRAD]; str += ')';
00461 }
00462 break;
00463
00464 default:
00465 ASSERT (FALSE);
00466 }
00467
00468 return str;
00469 }
00470
00471 fsSchedule* fsScheduleMgr::GetTask(int i)
00472 {
00473 return m_vTasks [i];
00474 }
00475
00476 CString fsScheduleMgr::HTSToStr(fsSchedule *task)
00477 {
00478 CString str;
00479
00480 switch (task->hts.enType)
00481 {
00482 case HTS_ONCE:
00483 str = LS (L_ONCE);
00484 break;
00485
00486 case HTS_DAILY:
00487 {
00488 LPCSTR pszDays [] = {LS (L_SUN), LS (L_MON), LS (L_TUE), LS (L_WED), LS (L_THU), LS (L_FRI), LS (L_SAT)};
00489 str = LS (L_ONDAYS); str += ' ';
00490 for (int i = 0; i < 7; i++)
00491 {
00492 if (task->hts.aWeeklyDays [i])
00493 {
00494 str += '"';
00495 str += pszDays [i];
00496 str += '"';
00497 str += ' ';
00498 }
00499 }
00500 }
00501 break;
00502
00503 case HTS_CONTINUOUSLY:
00504 str = LS (L_EVERY); str += ' ';
00505 if (task->hts.interval % (24*60) == 0)
00506 {
00507 CString s;
00508 s.Format ("%d %s", task->hts.interval / 24 / 60, LS (L_DAYS));
00509 str += s;
00510 }
00511 else if (task->hts.interval % 60 == 0)
00512 {
00513 CString s;
00514 s.Format ("%d %s", task->hts.interval / 60, LS (L_HOURS));
00515 str += s;
00516 }
00517 else
00518 {
00519 CString s;
00520 s.Format ("%d %s", task->hts.interval, LS (L_MIN_SMALL));
00521 str += s;
00522 }
00523 break;
00524
00525 case HTS_WHENISTART:
00526 str = LS (L_ATSTARTUP);
00527 break;
00528
00529 case HTS_WHENDIALINGSUCCESS:
00530 str = LS (L_AFTERDIALOK);
00531 break;
00532
00533 case HTS_WHENDIALINGFAILED:
00534 str = LS (L_DIALWASFAILED);
00535 break;
00536
00537 case HTS_WHENNODOWNLOADS:
00538 str = LS (L_WHENNOACTIVEDLDS);
00539 break;
00540
00541 case HTS_WHENSPEEDLOW:
00542 {
00543 CString str1;
00544 str1.Format (LS (L_WHENSPEEDLESS), task->hts.speedLow.uLowSpeed, task->hts.speedLow.uTimeInterval);
00545 str.Format ("%s %s", str1, LS (L_MIN_SMALL));
00546 }
00547 break;
00548
00549 case HTS_NOTHINGRECEIVED:
00550 str.Format ("%s %d %s", LS (L_WHENALLDLDSINERR), task->hts.uTimeNothingReceived, LS (L_MIN_SMALL));
00551 break;
00552
00553 case HTS_WHENDONE:
00554 str = LS (L_WHENDONE);
00555 break;
00556 }
00557
00558 return str;
00559 }
00560
00561 CString fsScheduleMgr::NextTimeToStr(fsSchedule *task)
00562 {
00563 CString str;
00564
00565 switch (task->hts.enType)
00566 {
00567 case HTS_ONCE:
00568 SYSTEMTIME time;
00569 FILETIME tm;
00570 GetLocalTime (&time);
00571 SystemTimeToFileTime (&time, &tm);
00572 if (CompareFileTime (&tm, &task->hts.next) >= 0)
00573 {
00574 str = LS (L_NEVER);
00575 break;
00576 }
00577
00578 case HTS_DAILY:
00579 case HTS_CONTINUOUSLY:
00580 {
00581 SYSTEMTIME time;
00582 CHAR strTime [1000], strDate [1000];
00583
00584 FileTimeToSystemTime (&task->hts.next, &time);
00585
00586 SystemTimeToStr (&time, strDate, strTime, FALSE);
00587
00588 str += strTime;
00589 str += " ";
00590 str += strDate;
00591 }
00592 break;
00593
00594 default:
00595 str = "";
00596 }
00597
00598 return str;
00599 }
00600
00601 CString fsScheduleMgr::LastTimeToStr(fsSchedule *task)
00602 {
00603 if (IsTimeUnknown (task->hts.last))
00604 return LS (L_NEVER);
00605
00606 SYSTEMTIME time;
00607 CHAR strTime [1000], strDate [1000];
00608 CString str;
00609
00610 FileTimeToSystemTime (&task->hts.last, &time);
00611
00612 SystemTimeToStr (&time, strDate, strTime, FALSE);
00613
00614 str += strTime;
00615 str += " ";
00616 str += strDate;
00617
00618 return str;
00619 }
00620
00621 void fsScheduleMgr::SetEventFunc(fntScheduleMgrEvents pfn, LPVOID lp)
00622 {
00623 m_pfnEvents = pfn;
00624 m_lpEvents = lp;
00625 }
00626
00627 void fsScheduleMgr::Event(fsSchedule* task, fsScheduleMgrEvent ev)
00628 {
00629 if (m_pfnEvents)
00630 m_pfnEvents (task, ev, m_lpEvents);
00631 }
00632
00633 BOOL fsScheduleMgr::SaveStateToFile(HANDLE hFile)
00634 {
00635 int cTasks = m_vTasks.size ();
00636
00637 DWORD dw;
00638
00639 if (!WriteFile (hFile, &cTasks, sizeof (cTasks), &dw, NULL))
00640 return FALSE;
00641
00642 for (int i = 0; i < cTasks; i++)
00643 {
00644 fsSchedule *task = m_vTasks [i];
00645
00646 if (!WriteFile (hFile, task, sizeof (fsSchedule), &dw, NULL))
00647 return FALSE;
00648
00649 switch (task->wts.enType)
00650 {
00651 case WTS_PROGRAM:
00652 if (!fsSaveStrToFile (task->wts.prog.pszName, hFile))
00653 return FALSE;
00654
00655 if (!fsSaveStrToFile (task->wts.prog.pszArgs, hFile))
00656 return FALSE;
00657 break;
00658
00659 case WTS_STARTDOWNLOAD:
00660 case WTS_STOPDOWNLOAD:
00661 if (!task->wts.pvIDs->save (hFile))
00662 return FALSE;
00663 break;
00664
00665 case WTS_DIAL:
00666 if (!fsSaveStrToFile (task->wts.dial.pszConnection, hFile))
00667 return FALSE;
00668 break;
00669
00670 case WTS_HANGUP:
00671 if (!fsSaveStrToFile (task->wts.pszHangupConnection, hFile))
00672 return FALSE;
00673 break;
00674 }
00675 }
00676
00677 return TRUE;
00678 }
00679
00680 BOOL fsScheduleMgr::LoadStateFromFile(HANDLE hFile)
00681 {
00682 FreeTasks ();
00683 m_uID = 0;
00684
00685 int cTasks;
00686
00687 DWORD dw;
00688
00689 if (!ReadFile (hFile, &cTasks, sizeof (cTasks), &dw, NULL) || dw != sizeof (cTasks))
00690 return FALSE;
00691
00692 UpdateCurrentTime ();
00693
00694 while (cTasks--)
00695 {
00696 fsSchedule *task = new fsSchedule;
00697
00698 if (!ReadFile (hFile, task, sizeof (fsSchedule), &dw, NULL) || dw != sizeof (fsSchedule))
00699 return FALSE;
00700
00701 switch (task->wts.enType)
00702 {
00703 case WTS_PROGRAM:
00704 if (!fsReadStrFromFile (&task->wts.prog.pszName, hFile))
00705 return FALSE;
00706
00707 if (!fsReadStrFromFile (&task->wts.prog.pszArgs, hFile))
00708 return FALSE;
00709 break;
00710
00711 case WTS_STARTDOWNLOAD:
00712 case WTS_STOPDOWNLOAD:
00713 fsnew1 (task->wts.pvIDs, fs::list <UINT>);
00714 if (!task->wts.pvIDs->load (hFile))
00715 return FALSE;
00716 break;
00717
00718 case WTS_DIAL:
00719 if (!fsReadStrFromFile (&task->wts.dial.pszConnection, hFile))
00720 return FALSE;
00721 break;
00722
00723 case WTS_HANGUP:
00724 if (!fsReadStrFromFile (&task->wts.pszHangupConnection, hFile))
00725 return FALSE;
00726 break;
00727 }
00728
00729 RepairNextTime (task);
00730 m_vTasks.add (task);
00731 }
00732
00733 return TRUE;
00734 }
00735
00736 void fsScheduleMgr::FreeTask(fsSchedule *task)
00737 {
00738 switch (task->wts.enType)
00739 {
00740 case WTS_PROGRAM:
00741 SAFE_DELETE_ARRAY (task->wts.prog.pszName);
00742 SAFE_DELETE_ARRAY (task->wts.prog.pszArgs);
00743 break;
00744
00745 case WTS_STARTDOWNLOAD:
00746 case WTS_STOPDOWNLOAD:
00747 SAFE_DELETE (task->wts.pvIDs);
00748 break;
00749
00750 case WTS_DIAL:
00751 SAFE_DELETE_ARRAY (task->wts.dial.pszConnection);
00752 break;
00753
00754 case WTS_HANGUP:
00755 SAFE_DELETE_ARRAY (task->wts.pszHangupConnection);
00756 break;
00757 }
00758 }
00759
00760 void fsScheduleMgr::FreeTasks()
00761 {
00762 for (int i = m_vTasks.size () - 1; i >= 0; i--)
00763 {
00764 FreeTask (m_vTasks [i]);
00765 delete m_vTasks [i];
00766 }
00767
00768 m_vTasks.clear ();
00769 }
00770
00771 int fsScheduleMgr::GetTaskCount()
00772 {
00773 return m_vTasks.size ();
00774 }
00775
00776 void fsScheduleMgr::DeleteTask(fsSchedule *task)
00777 {
00778 int index = FindTask (task);
00779
00780 if (index == -1)
00781 return;
00782
00783 Event (task, SME_TASK_WILLBEDELETED);
00784 m_vTasks.del (index);
00785
00786 if (task->wts.enType == WTS_STARTDOWNLOAD)
00787 UpdateTaskDownloads (task);
00788 }
00789
00790 int fsScheduleMgr::FindTask(fsSchedule *task)
00791 {
00792 for (int i = m_vTasks.size () - 1; i >= 0; i--)
00793 if (task == m_vTasks [i])
00794 return i;
00795
00796 return -1;
00797 }
00798
00799 void fsScheduleMgr::StartDownloads(fsSchedule *task)
00800 {
00801 DLDS_LIST vDldsToStart;
00802
00803 for (int i = task->wts.pvIDs->size () - 1; i >= 0; i--)
00804 {
00805 vmsDownloadSmartPtr dld = _DldsMgr.GetDownloadByID (task->wts.pvIDs->at (i));
00806
00807 if (dld != NULL && dld->pMgr->IsRunning () == FALSE)
00808 {
00809 BOOL bDone = dld->pMgr->IsDone ();
00810 BOOL bStart = TRUE;
00811
00812 if (bDone)
00813 {
00814 if (task->hts.enType == HTS_DAILY || task->hts.enType == HTS_CONTINUOUSLY)
00815 dld->pMgr->SetToRestartState ();
00816 else
00817 bStart = FALSE;
00818 }
00819
00820 if (bStart)
00821 {
00822 CString str;
00823
00824 str.Format ("%s \"%s\"", bDone ? LS (L_RESTART) : LS (L_START), dld->pMgr->get_URL ());
00825
00826 Event (str);
00827
00828 vDldsToStart.push_back (dld);
00829 }
00830 }
00831 else if (dld == NULL)
00832 {
00833 task->wts.pvIDs->del (i);
00834 }
00835 }
00836
00837 _DldsMgr.StartDownloads (vDldsToStart);
00838 }
00839
00840 void fsScheduleMgr::StopDownloads(fsSchedule *task)
00841 {
00842 DLDS_LIST vDlds;
00843
00844 for (int i = task->wts.pvIDs->size () - 1; i >= 0; i--)
00845 {
00846 vmsDownloadSmartPtr dld = _DldsMgr.GetDownloadByID (task->wts.pvIDs->at (i));
00847
00848 if (dld != NULL && dld->pMgr->IsRunning ())
00849 {
00850 CString str;
00851 str.Format ("%s \"%s\"", LS (L_STOP), dld->pMgr->get_URL ());
00852 Event (str);
00853
00854 vDlds.push_back (dld);
00855 }
00856 else if (dld == NULL)
00857 {
00858 task->wts.pvIDs->del (i);
00859 }
00860 }
00861
00862 _DldsMgr.StopDownloads (vDlds);
00863 }
00864
00865 void fsScheduleMgr::Dial(fsSchedule *task)
00866 {
00867 DWORD dw;
00868 CloseHandle (CreateThread (NULL, 0, _threadDial, task, 0, &dw));
00869 }
00870
00871 void fsScheduleMgr::Hangup(fsSchedule *task)
00872 {
00873 fsRASMgr mgr;
00874
00875 if (FALSE == mgr.EnumConnections ())
00876 return;
00877
00878 for (int i = mgr.GetConnectionCount () - 1; i >= 0; i--)
00879 {
00880 LPRASCONN conn = mgr.GetConnection (i);
00881 char szEv [1000];
00882 sprintf (szEv, "%s \"%s\"", LS (L_HANGUP), conn->szEntryName);
00883
00884 if (task->wts.pszHangupConnection)
00885 {
00886 if (stricmp (task->wts.pszHangupConnection, conn->szEntryName) == 0)
00887 {
00888 Event (szEv);
00889 fsRasHangUp (conn->hrasconn);
00890 break;
00891 }
00892 }
00893 else
00894 {
00895 Event (szEv);
00896 fsRasHangUp (conn->hrasconn);
00897 }
00898 }
00899 }
00900
00901 void fsScheduleMgr::Shutdown(fsSchedule *task)
00902 {
00903 HANDLE hProc = GetCurrentProcess ();
00904 HANDLE hToken;
00905 TOKEN_PRIVILEGES tp;
00906 LUID luid;
00907
00908 OpenProcessToken (hProc, TOKEN_ADJUST_PRIVILEGES, &hToken);
00909
00910 LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &luid);
00911 tp.PrivilegeCount = 1;
00912 tp.Privileges [0].Luid = luid;
00913 tp.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED;
00914
00915 AdjustTokenPrivileges (hToken, FALSE, &tp, 0, NULL, 0);
00916
00917 UINT uFlags = 0;
00918 switch (task->wts.shutdown.enShutdown)
00919 {
00920 case ST_SHUTDOWN:
00921 uFlags = EWX_POWEROFF;
00922 break;
00923
00924 case ST_RESTART:
00925 uFlags = EWX_REBOOT;
00926 break;
00927
00928 case ST_LOGOFF:
00929 uFlags = EWX_LOGOFF;
00930 break;
00931
00932 case ST_HIBERNATE:
00933 uFlags = 1 << 16;
00934 break;
00935
00936 case ST_STANDBY:
00937 uFlags = 1 << 17;
00938 break;
00939 }
00940
00941 if (task->wts.shutdown.bForce)
00942 uFlags |= EWX_FORCE;
00943
00944 LPCSTR szEv [] = { LS (L_SHUTDOWN), LS (L_RESTARTCOMP), LS (L_LOGOFF),
00945 LS (L_HIBERNATE), LS (L_STANDBY) };
00946 Event (szEv [task->wts.shutdown.enShutdown]);
00947
00948 DWORD dw;
00949 CloseHandle (CreateThread (NULL, 0, _threadShutdown, (LPVOID) uFlags, 0, &dw));
00950 }
00951
00952 DWORD WINAPI fsScheduleMgr::_threadDial(LPVOID lp)
00953 {
00954 fsSchedule *task = (fsSchedule*) lp;
00955
00956 fsDialInfo dial = task->wts.dial;
00957
00958 fsnew (dial.pszConnection, char, strlen (task->wts.dial.pszConnection) + 1);
00959 strcpy (dial.pszConnection, task->wts.dial.pszConnection);
00960
00961 CDialDlg dlg (NULL);
00962
00963 dlg.Init (&dial);
00964
00965 fsScheduleMgr *pThis = _pwndScheduler->GetMgr ();
00966
00967 CString str = LS (L_DIAL); str += " \"";
00968 str += dial.pszConnection;
00969 str += '"';
00970
00971 pThis->Event (str, SMET_INPROGRESS);
00972
00973 _DlgMgr.OnDoModal (&dlg);
00974
00975 if (IDOK == dlg.DoModal ())
00976 {
00977
00978 str.Format (LS (L_SUCCCONNECTED), dial.pszConnection);
00979 pThis->Event (str, SMET_S);
00980 }
00981 else
00982 {
00983 str.Format (LS (L_FAILEDCONNECTTO), dial.pszConnection);
00984 pThis->Event (str, SMET_E);
00985 }
00986
00987 _DlgMgr.OnEndDialog (&dlg);
00988
00989 delete [] dial.pszConnection;
00990
00991 return 0;
00992 }
00993
00994 void fsScheduleMgr::SetEventDescFunc(fntScheduleMgrEventDesc pfn, LPVOID lp)
00995 {
00996 m_pfnEventDesc = pfn;
00997 m_lpEventDesc = lp;
00998 }
00999
01000 void fsScheduleMgr::Event(LPCSTR pszEvent, fsScheduleMgrEventType enType)
01001 {
01002 if (m_pfnEventDesc)
01003 m_pfnEventDesc (pszEvent, enType, m_lpEventDesc);
01004 }
01005
01006 void fsScheduleMgr::LaunchProgram(fsSchedule *task)
01007 {
01008 DWORD dwRet = (DWORD) ShellExecute (NULL, "open", task->wts.prog.pszName, task->wts.prog.pszArgs,
01009 NULL, SW_SHOW);
01010 if (dwRet > 32)
01011 {
01012 CString str = '"';
01013 str += task->wts.prog.pszName;
01014 str += "\" ";
01015 str += LS (L_LAUNCHEDSUCC);
01016 Event (str);
01017 }
01018 else
01019 {
01020 CString str;
01021 char szErr [200];
01022 SetLastError (dwRet);
01023 if (dwRet)
01024 fsErrorToStr (szErr, sizeof (szErr));
01025 else
01026 strcpy (szErr, LS (L_OUTOFMEMORY));
01027 str.Format ("%s %s [%s]", LS (L_CANTLAUNCH), task->wts.prog.pszName, szErr);
01028 Event (str, SMET_E);
01029 }
01030 }
01031
01032 void fsScheduleMgr::ExciteEvent(fsExternalEvent ev)
01033 {
01034 fsWhenToStartType hts = ExternalEventToHTS (ev);
01035
01036 if (ev == EV_STARTUP)
01037 {
01038 DWORD dw;
01039 CloseHandle (
01040 CreateThread (NULL, 0, _threadScheduleMgr, this, 0, &dw));
01041 }
01042
01043 fs::list <fsSchedule*> vTasks;
01044
01045 for (int i = 0; i < m_vTasks.size (); i++)
01046 {
01047 fsSchedule *task = m_vTasks [i];
01048
01049 if ((task->dwFlags & SCHEDULE_ENABLED) == 0)
01050 continue;
01051
01052 fsWhenToStartType htsTask = task->hts.enType;
01053 if (htsTask == HTS_WHENDONE)
01054 htsTask = HTS_WHENNODOWNLOADS;
01055
01056 if (hts == htsTask)
01057 {
01058 if (ev == EV_STARTUP &&
01059 (task->wts.enType == WTS_SHUTDOWN || task->wts.enType == WTS_EXIT))
01060 {
01061 MessageBox (0, LS (L_SCHEDULERESTOEXIT), LS (L_SCHEDULER), MB_ICONEXCLAMATION);
01062 task->dwFlags &= ~ SCHEDULE_ENABLED;
01063 continue;
01064 }
01065
01066 if (task->wts.enType == WTS_SHUTDOWN)
01067 vTasks.insert (0, task);
01068 else if (task->wts.enType == WTS_EXIT)
01069 vTasks.add (task);
01070 else
01071 StartTask (task);
01072 }
01073 }
01074
01075 for (i = 0; i < vTasks.size (); i++)
01076 StartTask (vTasks [i]);
01077 }
01078
01079 fsWhenToStartType fsScheduleMgr::ExternalEventToHTS(fsExternalEvent ev)
01080 {
01081 switch (ev)
01082 {
01083 case EV_STARTUP:
01084 return HTS_WHENISTART;
01085
01086 case EV_DIALINGSUCCESS:
01087 return HTS_WHENDIALINGSUCCESS;
01088
01089 case EV_DIALINGFAILED:
01090 return HTS_WHENDIALINGFAILED;
01091
01092 case EV_NODOWNLOADS:
01093 return HTS_WHENNODOWNLOADS;
01094
01095 default:
01096 ASSERT (FALSE);
01097 return HTS_ONCE;
01098 }
01099 }
01100
01101 void fsScheduleMgr::ManageHalfEvents()
01102 {
01103 fs::list <fsSchedule*> vTasks;
01104
01105 if (_DldsMgr.IsRunning () == FALSE)
01106 return;
01107
01108 for (int i = m_vTasks.size () - 1; i >= 0; i--)
01109 {
01110 fsSchedule *task = m_vTasks [i];
01111
01112 if ((task->dwFlags & SCHEDULE_ENABLED) == 0)
01113 continue;
01114
01115 UINT uSpeed = task->hts.speedLow.uLowSpeed;
01116 UINT uInterval = task->hts.speedLow.uTimeInterval;
01117
01118 switch (task->hts.enType)
01119 {
01120 case HTS_NOTHINGRECEIVED:
01121 case HTS_WHENDONE:
01122 uSpeed = 1;
01123 uInterval = task->hts.uTimeNothingReceived;
01124 case HTS_WHENSPEEDLOW:
01125
01126 if (IsTimeUnknown (task->hts.last) ||
01127 fsGetTimeDelta (&m_curTime, &task->hts.last) >= uInterval*60)
01128 {
01129
01130 if (_DldsMgr.IsSummarySpeedWasLessThan (uSpeed+1, uInterval*60))
01131 {
01132 switch (task->wts.enType)
01133 {
01134 case WTS_EXIT:
01135 vTasks.add (task);
01136 break;
01137
01138 case WTS_SHUTDOWN:
01139 vTasks.insert (0, task);
01140 break;
01141
01142 default:
01143 StartTask (task);
01144 }
01145 }
01146 }
01147 }
01148 }
01149
01150 for (i = 0; i < vTasks.size (); i++)
01151 StartTask (vTasks [i]);
01152 }
01153
01154 void fsScheduleMgr::Stop()
01155 {
01156 m_bNeedExit = TRUE;
01157 while (m_bNeedExit)
01158 Sleep (5);
01159 }
01160
01161 DWORD WINAPI fsScheduleMgr::_threadShutdown(LPVOID uFlags)
01162 {
01163 Sleep (1000);
01164
01165 if ((DWORD)uFlags & ((1 << 16) | (1 << 17)))
01166 {
01167 BOOL bHibernate = ((DWORD)uFlags & (1 << 16)) != 0;
01168 vmsSetSuspendState (bHibernate, ((DWORD)uFlags & EWX_FORCE) != 0, FALSE);
01169 return 0;
01170 }
01171
01172 LOG ("Shutting down computer..." << nl);
01173 LOG ("goto OnAppExit..." << nl);
01174
01175 _PluginMgr.OnAppExit (FALSE);
01176
01177 LOG ("saving history..." << nl);
01178
01179 ((CFdmApp*)AfxGetApp ())->SaveSettings ();
01180 ((CFdmApp*)AfxGetApp ())->SaveHistory ();
01181
01182 LOG ("saving state..." << nl);
01183
01184 ((CMainFrame*) AfxGetApp ()->m_pMainWnd)->SaveState ();
01185
01186 LOG ("performing shutdown..." << nl);
01187
01188 ExitWindowsEx ((UINT) uFlags, 0);
01189
01190 LOG ("did shutdown" << nl);
01191
01192 return 0;
01193 }
01194
01195 BOOL fsScheduleMgr::IsDownloadScheduled(vmsDownloadSmartPtr dld)
01196 {
01197 for (int i = m_vTasks.size () - 1; i >= 0; i--)
01198 {
01199 fsSchedule *task = m_vTasks [i];
01200
01201 if (task->wts.enType == WTS_STARTDOWNLOAD && (task->dwFlags & SCHEDULE_ENABLED))
01202 {
01203
01204 for (int j = task->wts.pvIDs->size () - 1; j >= 0; j--)
01205 {
01206 if (task->wts.pvIDs->at (j) == dld->nID)
01207 {
01208 if (task->hts.enType == HTS_ONCE)
01209 {
01210
01211 if (IsTimeUnknown (task->hts.next) == FALSE && CompareFileTime (&task->hts.next, &m_curTime) == 1)
01212 return TRUE;
01213 }
01214 else
01215 return TRUE;
01216 }
01217 }
01218 }
01219 }
01220
01221 return FALSE;
01222 }
01223
01224 fsSchedule* fsScheduleMgr::GetScheduleDLTask(DLDS_LIST &vDlds, BOOL bStartDL)
01225 {
01226 fsWhatToStartType enWTS = bStartDL ? WTS_STARTDOWNLOAD : WTS_STOPDOWNLOAD;
01227
01228 int cDlds = vDlds.size ();
01229 ASSERT (cDlds);
01230
01231 for (int i = m_vTasks.size () - 1; i >= 0; i--)
01232 {
01233 fsSchedule *task = m_vTasks [i];
01234 if (task->wts.enType == enWTS)
01235 {
01236 if (task->wts.pvIDs->size () == cDlds)
01237 {
01238 for (int j = 0; j < cDlds; j++)
01239 {
01240 for (int k = 0; k < cDlds; k++)
01241 if (vDlds [j]->nID == task->wts.pvIDs->at (k))
01242 break;
01243
01244 if (k == cDlds)
01245 break;
01246 }
01247
01248 if (j == cDlds)
01249 return task;
01250 }
01251 }
01252 }
01253
01254 return NULL;
01255 }
01256
01257 void fsScheduleMgr::UpdateCurrentTime()
01258 {
01259 SYSTEMTIME time;
01260 GetLocalTime (&time);
01261 SystemTimeToFileTime (&time, &m_curTime);
01262 }
01263
01264 int fsScheduleMgr::FindTask(fsWhatToStartType enType, int iStartPos)
01265 {
01266 for (int i = iStartPos+1; i < m_vTasks.size (); i++)
01267 {
01268 if (m_vTasks [i]->wts.enType == enType)
01269 return i;
01270 }
01271
01272 return -1;
01273 }
01274
01275 void fsScheduleMgr::UpdateTaskDownloads(fsSchedule *task)
01276 {
01277 DLDS_LIST vDlds;
01278
01279 for (int j = 0; j < task->wts.pvIDs->size (); j++)
01280 {
01281 vmsDownloadSmartPtr dld = _DldsMgr.GetDownloadByID (task->wts.pvIDs->at (j));
01282 if (dld)
01283 _pwndDownloads->UpdateDownload (dld);
01284 }
01285 }
01286
01287 void fsScheduleMgr::OnTaskUpdated(fsSchedule *task)
01288 {
01289 if (task->wts.enType == WTS_STARTDOWNLOAD)
01290 {
01291 UpdateTaskDownloads (task);
01292 _pwndSpider->UpdateTasksIcons ();
01293 }
01294
01295 Event (task, SME_TASK_UPDATED);
01296 }
01297
01298 void fsScheduleMgr::RepairTasksNextTimes()
01299 {
01300 for (int i = 0; i < m_vTasks.size (); i++)
01301 RepairNextTime (m_vTasks [i]);
01302 }