source: trunk/SchedulerView.cpp @ 883

Revision 883, 68.1 KB checked in by lowjoel, 6 years ago (diff)

Fixed the next-run time column for tasks which run at midnight.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// SchedulerView.cpp
2// $Id$
3//
4// Eraser. Secure data removal. For Windows.
5// Copyright © 1997-2001  Sami Tolvanen (sami@tolvanen.com).
6// Copyright © 2007 The Eraser Project
7//
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU General Public License
10// as published by the Free Software Foundation; either version 2
11// of the License, or (at your option) any later version.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21// 02111-1307, USA.
22
23#include "stdafx.h"
24#include "Eraser.h"
25#include "EraserDoc.h"
26#include "shared\key.h"
27#include "SchedulerView.h"
28
29#include "TaskPropertySheet.h"
30#include "shared\FileHelper.h"
31#include "EraserUI\DriveCombo.h"
32#include "EraserUI\GfxPopupMenu.h"
33#include "EraserUI\TimeOutMessageBox.h"
34
35#include "EraserDll\OptionPages.h"
36#include "EraserDll\options.h"
37#include "EraserDll\EraserDllInternal.h"
38
39#ifdef _DEBUG
40#define new DEBUG_NEW
41#undef THIS_FILE
42static char THIS_FILE[] = __FILE__;
43#endif
44
45enum Columns
46{
47    ColumnName,
48    ColumnType,
49    ColumnLast,
50    ColumnNext,
51    ColumnSchedule
52};
53
54static const int iColumnCount = 5;
55
56static const LPTSTR szColumnNames[iColumnCount] =
57{
58    "Name",
59    "Type",
60    "Last Run",
61    "Next Run",
62    "Schedule"
63};
64
65static const int iMinFirstColumnWidth = 100;
66static const int iOtherColumnWidth = 370;
67
68static const int iColumnWidths[] =
69{
70    -1,
71    100,
72    90,
73    90,
74    90
75};
76
77#define FIRST_TIMER (WM_USER + 42) // HHGTG
78
79// for accessing the process counter
80static CEvent evWaitForCounterAccess(TRUE, TRUE);
81
82#define counterLock() \
83    WaitForSingleObject(evWaitForCounterAccess, INFINITE); \
84    evWaitForCounterAccess.ResetEvent()
85#define counterUnlock() \
86    evWaitForCounterAccess.SetEvent()
87
88/////////////////////////////////////////////////////////////////////////////
89// CSchedulerView
90
91IMPLEMENT_DYNCREATE(CSchedulerView, CFlatListView)
92
93CSchedulerView::CSchedulerView() :
94m_uNextTimerID(FIRST_TIMER)
95{
96    TRACE("CSchedulerView::CSchedulerView\n");
97}
98
99CSchedulerView::~CSchedulerView()
100{
101    TRACE("CSchedulerView::~CSchedulerView\n");
102}
103
104
105BEGIN_MESSAGE_MAP(CSchedulerView, CFlatListView)
106    ON_WM_CONTEXTMENU()
107    //{{AFX_MSG_MAP(CSchedulerView)
108    ON_WM_SIZE()
109    ON_COMMAND(ID_FILE_NEW_TASK, OnFileNewTask)
110    ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE_TASK, OnUpdateEditDeleteTask)
111    ON_COMMAND(ID_EDIT_DELETE_TASK, OnEditDeleteTask)
112    ON_UPDATE_COMMAND_UI(ID_EDIT_PROPERTIES, OnUpdateEditProperties)
113    ON_COMMAND(ID_EDIT_PROPERTIES, OnEditProperties)
114    ON_WM_TIMER()
115    ON_WM_DESTROY()
116    ON_WM_LBUTTONDBLCLK()
117    ON_UPDATE_COMMAND_UI(ID_PROCESS_RUN, OnUpdateProcessRun)
118    ON_UPDATE_COMMAND_UI(ID_PROCESS_RUNALL, OnUpdateProcessRunAll)
119    ON_COMMAND(ID_PROCESS_RUN, OnProcessRun)
120    ON_COMMAND(ID_PROCESS_RUNALL, OnProcessRunAll)
121    ON_UPDATE_COMMAND_UI(ID_PROCESS_STOP, OnUpdateProcessStop)
122    ON_COMMAND(ID_PROCESS_STOP, OnProcessStop)
123    ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdateEditSelectAll)
124    ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
125    ON_COMMAND(ID_EDIT_REFRESH, OnEditRefresh)
126    //}}AFX_MSG_MAP
127    ON_MESSAGE(WM_ERASERNOTIFY, OnEraserNotify)
128    ON_UPDATE_COMMAND_UI(ID_INDICATOR_ITEMS, OnUpdateItems)
129END_MESSAGE_MAP()
130
131/////////////////////////////////////////////////////////////////////////////
132// CSchedulerView drawing
133
134void CSchedulerView::OnDraw(CDC* /*pDC*/)
135{
136
137}
138
139/////////////////////////////////////////////////////////////////////////////
140// CSchedulerView diagnostics
141
142#ifdef _DEBUG
143void CSchedulerView::AssertValid() const
144{
145    CFlatListView::AssertValid();
146}
147
148void CSchedulerView::Dump(CDumpContext& dc) const
149{
150    CFlatListView::Dump(dc);
151}
152#endif //_DEBUG
153
154/////////////////////////////////////////////////////////////////////////////
155// CSchedulerView message handlers
156
157BOOL CSchedulerView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
158{
159    TRACE("CSchedulerView::Create\n");
160
161    dwStyle |= LVS_REPORT | LVS_NOSORTHEADER | LVS_SORTASCENDING | LVS_SHOWSELALWAYS;
162
163    if (CFlatListView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext))
164    {
165        CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
166        CListCtrl& lcList = GetListCtrl();
167
168        try
169        {
170            CRect rClient;
171            lcList.GetClientRect(&rClient);
172
173            int iWidth = rClient.Width() - iOtherColumnWidth - GetSystemMetrics(SM_CXBORDER);
174
175            if (iWidth < iMinFirstColumnWidth) iWidth = iMinFirstColumnWidth;
176
177            LVCOLUMN lvc;
178            ZeroMemory(&lvc, sizeof(LVCOLUMN));
179
180            lvc.mask        = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
181            lvc.fmt         = LVCFMT_LEFT;
182            lvc.pszText     = szColumnNames[ColumnName];
183            lvc.cx          = iWidth;
184            lvc.iSubItem    = ColumnName;
185            lcList.InsertColumn(ColumnName, &lvc);
186
187            for (int i = 1; i <= (iColumnCount - 1); i++)
188            {
189                lvc.pszText = szColumnNames[i];
190                lvc.cx = iColumnWidths[i];
191                lvc.iSubItem = i;
192                lcList.InsertColumn(i, &lvc);
193            }
194
195            lcList.SetExtendedStyle(LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
196//            lcList.SetImageList(&pDoc->m_smallImageList, LVSIL_SMALL);
197            lcList.SetImageList(pDoc->m_smallImageList, LVSIL_SMALL);
198
199            CFlatHeaderCtrl *pfhFlatHeader = (CFlatHeaderCtrl*)lcList.GetHeaderCtrl();
200
201            if (pfhFlatHeader != NULL)
202            {
203                pfhFlatHeader->SetImageList(&pDoc->m_ilHeader);
204
205                HDITEMEX hie;
206
207                hie.m_iMinWidth = iMinFirstColumnWidth;
208                hie.m_iMaxWidth = -1;
209
210                pfhFlatHeader->SetItemEx(ColumnName, &hie);
211
212                HDITEM hditem;
213
214                hditem.mask = HDI_FORMAT | HDI_IMAGE;
215                pfhFlatHeader->GetItem(ColumnName, &hditem);
216
217                hditem.fmt      |= HDF_IMAGE;
218                hditem.iImage   = IconEraser;
219                pfhFlatHeader->SetItem(ColumnName, &hditem);
220
221                hditem.mask = HDI_FORMAT | HDI_IMAGE;
222                pfhFlatHeader->GetItem(ColumnSchedule, &hditem);
223
224                hditem.fmt      |= HDF_IMAGE;
225                hditem.iImage   = IconClock;
226                pfhFlatHeader->SetItem(ColumnSchedule, &hditem);
227            }
228
229            ModifyStyleEx(WS_EX_CLIENTEDGE, 0);
230
231            return TRUE;
232        }
233        catch (CException *e)
234        {
235            ASSERT(FALSE);
236            REPORT_ERROR(e);
237            e->Delete();
238        }
239    }
240
241    return FALSE;
242}
243
244void CSchedulerView::OnSize(UINT nType, int cx, int cy)
245{
246    TRACE("CSchedulerView::OnSize\n");
247
248    CFlatListView::OnSize(nType, cx, cy);
249    ResizeColumns();
250}
251
252void CSchedulerView::ResizeColumns()
253{
254    TRACE("CSchedulerView::ResizeColumns\n");
255
256    CListCtrl& lc = GetListCtrl();
257
258    CRect rClient;
259    lc.GetClientRect(&rClient);
260
261    int iWidth;
262    int iColumn;
263    int iRest = 0;
264
265    for (iColumn = (iColumnCount - 1); iColumn >= 1; iColumn--)
266        iRest += lc.GetColumnWidth(iColumn);
267
268    iWidth = rClient.Width() - iRest - GetSystemMetrics(SM_CXBORDER);
269
270    if (iWidth < iMinFirstColumnWidth)
271        iWidth = iMinFirstColumnWidth;
272
273    lc.SetColumnWidth(0, iWidth);
274}
275
276void CSchedulerView::OnContextMenu(CWnd*, CPoint point)
277{
278    TRACE("CSchedulerView::OnContextMenu\n");
279
280    try
281    {
282        if (point.x == -1 && point.y == -1)
283        {
284            CRect rect;
285            GetClientRect(rect);
286            ClientToScreen(rect);
287
288            point = rect.TopLeft();
289            point.Offset(5, 5);
290        }
291
292        CGfxPopupMenu menu;
293        menu.LoadMenu(IDR_MENU_SCHEDULERVIEW, IDR_MAINFRAME, this);
294
295        CWnd* pWndPopupOwner = this;
296
297        while (pWndPopupOwner->GetStyle() & WS_CHILD)
298            pWndPopupOwner = pWndPopupOwner->GetParent();
299
300        menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
301            pWndPopupOwner);
302
303        menu.DestroyMenu();
304    }
305    catch (CException *e)
306    {
307        ASSERT(FALSE);
308        REPORT_ERROR(e);
309        e->Delete();
310    }
311}
312
313
314void CSchedulerView::OnInitialUpdate()
315{
316    TRACE("CSchedulerView::OnInitialUpdate\n");
317
318    SetTimers();
319
320    if (!IsWindow(m_pbProgress.GetSafeHwnd()))
321        m_pbProgress.Create("", 30, 100, TRUE, 0);
322
323    CFlatListView::OnInitialUpdate();
324}
325
326void CSchedulerView::OnFileNewTask()
327{
328    TRACE("CSchedulerView::OnFileNewTask\n");
329   
330    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
331    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
332
333    try
334    {
335        CTaskPropertySheet tps(TRUE, TRUE);
336        LibrarySettings plsTmp;
337        loadLibrarySettings(&plsTmp);       
338        if (tps.DoModal() == IDOK)
339        {
340            if (tps.m_pgData.m_strSelectedDrive.IsEmpty() &&
341                tps.m_pgData.m_strFolder.IsEmpty() &&
342                tps.m_pgData.m_strFile.IsEmpty())
343            {
344                // no data
345                return;
346            }
347
348            COleDateTime odtTime;
349            Schedule scWhen;
350
351            odtTime = tps.m_pgSchedule.m_odtTime;
352            scWhen = static_cast<Schedule>(tps.m_pgSchedule.m_iWhen);
353
354            // save the new scheduled task
355
356            if (pDoc->m_bLog && !pDoc->m_bLogOnlyErrors)
357            {
358                CString strAction;
359                CString strData;
360
361                switch (tps.m_pgData.m_tType)
362                {
363                case Drive:
364                    strData = tps.m_pgData.m_strSelectedDrive;
365                    break;
366                case Folder:
367                    strData = tps.m_pgData.m_strFolder;
368                    break;
369                case File:
370                    strData = tps.m_pgData.m_strFile;
371                    break;
372                default:
373                    NODEFAULT;
374                };
375                AfxFormatString1(strAction, IDS_ACTION_NEW, strData);
376                pDoc->LogAction(strAction);
377            }
378
379            CScheduleItem *psiItem = new CScheduleItem();
380            psiItem->SetSchedule(scWhen);
381            psiItem->SetTime((WORD)odtTime.GetHour(), (WORD)odtTime.GetMinute());
382            psiItem->FinishAction(tps.m_pgData.m_dwFinishAction);
383
384            switch (tps.m_pgData.m_tType)
385            {
386            case Drive:
387                psiItem->SetDrive(tps.m_pgData.m_strSelectedDrive);
388                break;
389            case Folder:
390                psiItem->SetFolder(tps.m_pgData.m_strFolder);
391                psiItem->RemoveFolder(tps.m_pgData.m_bRemoveFolder);
392                psiItem->Subfolders(tps.m_pgData.m_bSubfolders);
393                psiItem->OnlySubfolders(tps.m_pgData.m_bRemoveOnlySub);
394                break;
395            case File:
396                psiItem->SetFile(tps.m_pgData.m_strFile);
397                psiItem->UseWildcards(tps.m_pgData.m_bUseWildCards);
398                psiItem->WildcardsInSubfolders(tps.m_pgData.m_bWildCardsInSubfolders);
399                break;
400            default:
401                NODEFAULT;
402            };
403   
404            psiItem->CalcNextTime();
405
406            if (!pDoc->AddScheduledTask(psiItem))
407            {
408                delete psiItem;
409                psiItem = 0;
410            }
411            else
412            {
413                psiItem->m_uTimerID = GetNextTimerID();
414
415                if (!SetTimer(psiItem->m_uTimerID, psiItem->GetTimeSpan(), NULL))
416                {
417                    AfxTimeOutMessageBox(IDS_ERROR_TIMER, MB_ICONERROR);
418
419                    if (pDoc->m_bLog)
420                        pDoc->LogAction(IDS_ERROR_TIMER);
421                }
422            }
423
424                // Here we just add it to the bootup sequence if it is on boot
425                if (scWhen == Reboot) 
426                {
427                //Here we are setting the appropriate entry into the Registry Key :
428                //HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
429                //The entry should be in Name - Data pair, where Name is the name of the application and Data is the path of the executable
430                    CKey kReg;
431                    CString m_strExePath;
432                    CString m_strName;
433                    char Fullname[260];
434                    char Filename[260];
435                    char Extension[5];
436                    char Pathname[260];
437                    char myDrive[10];
438                    char *buffer = new char[260];
439
440                    if (kReg.Open(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run"))
441                    {
442                         GetModuleFileName(AfxGetInstanceHandle(),Fullname,sizeof Fullname);
443                        _splitpath(Fullname,myDrive,Pathname,Filename,Extension); 
444                        strcpy(buffer,myDrive);
445                        strncat(buffer,Pathname,250);
446                        strncpy(Pathname,buffer,260);
447                        delete buffer;
448                        m_strExePath = '"';
449                        //gt m_strExePath+=  CString(Pathname);
450                        m_strExePath+= "Eraserl.exe";
451                        m_strExePath+= '"';
452                        switch (tps.m_pgData.m_tType)
453                        {
454                            case Drive:
455                                m_strExePath+= " -disk " + tps.m_pgData.m_strSelectedDrive;
456                                break;
457                            case Folder:
458                                m_strExePath+= " -folder ";
459                                m_strExePath+= '"';
460                                m_strExePath+= tps.m_pgData.m_strFolder;
461                                m_strExePath+= '"';
462                                if (tps.m_pgData.m_bRemoveFolder==FALSE) {m_strExePath+= " -keepfolder ";}
463                                if (tps.m_pgData.m_bSubfolders) {m_strExePath+= " -subfolders ";}
464                                break;
465                            case File:
466                                m_strExePath+= " -file ";
467                                m_strExePath+= '"';
468                                m_strExePath+= tps.m_pgData.m_strFile;
469                                m_strExePath+= '"';
470                                break;
471
472                            default:
473                                NODEFAULT;
474                        };
475                        kReg.SetValue(m_strExePath, psiItem->GetId());
476                        m_strExePath.ReleaseBuffer();
477                        kReg.Close();
478                    }
479                }
480            UpdateList();
481           
482            LibrarySettings* plsTmp1 = tps.m_pPageFileMethodOptions->GetLibSettings();
483            psiItem->m_bMethod = plsTmp1->m_nFileMethodID;
484            psiItem->m_uEraseItems = plsTmp1->m_uItems;
485            psiItem->m_nRndPass = plsTmp1->m_nFileRandom;
486            plsTmp1->m_nFileMethodID = plsTmp.m_nFileMethodID;
487            plsTmp1->m_nFileRandom = plsTmp.m_nFileRandom;
488            plsTmp1->m_uItems = plsTmp.m_uItems;
489            saveLibrarySettings(plsTmp1);       
490           
491            pDoc->CalcNextAssignment();
492            pDoc->UpdateToolTip();
493            pDoc->SaveTasksToDefault();
494        }
495    }
496    catch (CException *e)
497    {
498        ASSERT(FALSE);
499        REPORT_ERROR(e);
500        e->Delete();
501    }
502}
503
504void CSchedulerView::OnUpdateEditDeleteTask(CCmdUI* pCmdUI)
505{
506    CListCtrl& lc = GetListCtrl();
507    pCmdUI->Enable(lc.GetSelectedCount() > 0);
508}
509
510void CSchedulerView::OnEditDeleteTask()
511{
512    TRACE("CSchedulerView::OnEditDeleteTask\n");
513    CString strData;
514    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
515    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
516
517    try
518    {
519        CListCtrl& lc = GetListCtrl();
520
521        if (lc.GetSelectedCount() > 0 && AfxMessageBox("Are you sure you want to "
522            "delete the selected tasks?", MB_YESNO | MB_ICONQUESTION) == IDYES)
523        {
524            int nItem;
525            INT_PTR iSize = pDoc->m_paScheduledTasks.GetSize();
526            DWORD_PTR nIndex;
527            CScheduleItem *psiItem = 0;
528
529            POSITION pos = lc.GetFirstSelectedItemPosition();
530
531            while (pos)
532            {
533                nItem = lc.GetNextSelectedItem(pos);
534                nIndex = lc.GetItemData(nItem);
535
536                if (nIndex >= 0 && nIndex < iSize)
537                {
538                    psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[nIndex]);
539                    if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
540                    {
541                        if (pDoc->m_bLog && !pDoc->m_bLogOnlyErrors)
542                        {
543                            CString strAction;
544                           
545                            psiItem->GetData(strData);
546                            AfxFormatString1(strAction, IDS_ACTION_DELETE, strData);
547                            pDoc->LogAction(strAction);
548                        }
549
550                        // kill the timer assigned to the task
551                        KillTimer(psiItem->m_uTimerID);
552
553                        // turn off the thread just in case it is running
554                        TerminateThread(psiItem);
555                        if (psiItem->GetSchedule() == Reboot) 
556                        {
557                            CKey kReg;
558                            if (kReg.Open(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run"))
559                            {
560                                kReg.DeleteValue(psiItem->GetId());
561                                kReg.Close();
562                            }
563                        }
564                           
565                        // remove it from the queue just in case it happens to be there
566                        RemoveTaskFromQueue(psiItem);
567
568                        delete psiItem;
569                        psiItem = 0;
570
571                        pDoc->m_paScheduledTasks.SetAt(nIndex, 0);
572                    }
573                }
574            }
575
576            UpdateList();
577            pDoc->CalcNextAssignment();
578            pDoc->UpdateToolTip();
579            pDoc->SaveTasksToDefault();
580        }
581    }
582    catch (CException *e)
583    {
584        ASSERT(FALSE);
585        REPORT_ERROR(e);
586        e->Delete();
587    }
588}
589
590void CSchedulerView::OnUpdateEditProperties(CCmdUI* pCmdUI)
591{
592    CListCtrl& lc = GetListCtrl();
593    pCmdUI->Enable(lc.GetSelectedCount() == 1);
594}
595
596void CSchedulerView::OnEditProperties()
597{
598    TRACE("CSchedulerView::OnEditProperties\n");
599
600    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
601    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
602
603    try
604    {
605        CListCtrl& lc = GetListCtrl();
606
607        if (lc.GetSelectedCount() == 1)
608        {
609            POSITION pos = lc.GetFirstSelectedItemPosition();
610
611            int nItem = lc.GetNextSelectedItem(pos);
612            DWORD_PTR nIndex = lc.GetItemData(nItem);
613
614            if (nIndex >= 0 && nIndex < pDoc->m_paScheduledTasks.GetSize())
615            {
616                CScheduleItem *psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[nIndex]);
617                if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
618                {
619                    CString strData;
620                    CTaskPropertySheet tps(TRUE, FALSE);
621
622                    LibrarySettings plsTmp;
623                    loadLibrarySettings(&plsTmp);
624                    if (psiItem->m_bMethod) {
625                        BOOL bExist = FALSE;
626                        for (int i = 0; i < plsTmp.m_nCMethods; i++) 
627                            bExist = (plsTmp.m_lpCMethods->m_nMethodID == psiItem->m_bMethod);
628                        if (bExist||(psiItem->m_bMethod == GUTMANN_METHOD_ID || psiItem->m_bMethod == DOD_METHOD_ID ||
629                            psiItem->m_bMethod == DOD_E_METHOD_ID || psiItem->m_bMethod == RANDOM_METHOD_ID ||
630                            psiItem->m_bMethod == FL2KB_METHOD_ID)){
631                            //tps.m_pPageFileMethodOptions->SetLibSettings(&plsTmp);
632                            tps.m_pPageFileMethodOptions->GetLibSettings()->m_nFileMethodID=psiItem->m_bMethod;
633                            tps.m_pPageFileMethodOptions->GetLibSettings()->m_uItems = psiItem->m_uEraseItems; 
634                            tps.m_pPageFileMethodOptions->GetLibSettings()->m_nFileRandom = psiItem->m_nRndPass;                           
635                        }
636                        else {
637                            tps.m_pPageFileMethodOptions->GetLibSettings()->m_nFileMethodID=plsTmp.m_nFileMethodID;
638                            psiItem->m_bMethod = plsTmp.m_nFileMethodID;
639                            psiItem->m_nRndPass = plsTmp.m_nFileRandom;
640                            psiItem->m_uEraseItems = plsTmp.m_uItems;
641                        }                   
642                    }
643
644                    tps.m_pgData.m_tType = psiItem->GetType();
645                    tps.m_pgData.m_bRemoveFolder = psiItem->RemoveFolder();
646                    tps.m_pgData.m_bSubfolders = psiItem->Subfolders();
647                    tps.m_pgData.m_bRemoveOnlySub = psiItem->OnlySubfolders();
648                    tps.m_pgData.m_bUseWildCards = psiItem->UseWildcards();
649                    tps.m_pgData.m_bWildCardsInSubfolders = psiItem->WildcardsInSubfolders();
650                    tps.m_pgData.m_dwFinishAction = psiItem->FinishAction();
651
652                    psiItem->GetData(strData);
653
654                    switch (tps.m_pgData.m_tType)
655                    {
656                    case Drive:
657                        tps.m_pgData.m_strSelectedDrive = strData;
658                        break;
659                    case Folder:
660                        tps.m_pgData.m_strFolder = strData;
661                        break;
662                    case File:
663                        tps.m_pgData.m_strFile = strData;
664                        break;
665                    default:
666                        NODEFAULT;
667                    };
668
669                    tps.m_pgSchedule.m_odtTime.SetTime(psiItem->GetHour(), psiItem->GetMinute(), 0);
670                    tps.m_pgSchedule.m_iWhen = static_cast<int>(psiItem->GetSchedule());
671                    tps.m_pgStatistics.m_lpts = psiItem->GetStatistics();
672
673                    if (tps.DoModal() == IDOK)
674                    {
675                        if (tps.m_pgData.m_strSelectedDrive.IsEmpty() &&
676                            tps.m_pgData.m_strFolder.IsEmpty() &&
677                            tps.m_pgData.m_strFile.IsEmpty())
678                        {
679                            // no data
680                            return;
681                        }
682
683                        if (psiItem->IsRunning())
684                        {
685                            if (AfxTimeOutMessageBox(IDS_QUESTION_INTERRUPT, MB_ICONWARNING | MB_YESNO) != IDYES)
686                                return;
687
688                            TerminateThread(psiItem);
689                        }
690
691                        KillTimer(psiItem->m_uTimerID);
692
693                        psiItem->SetSchedule(static_cast<Schedule>(tps.m_pgSchedule.m_iWhen));
694                        psiItem->SetTime((WORD)tps.m_pgSchedule.m_odtTime.GetHour(),
695                            (WORD)tps.m_pgSchedule.m_odtTime.GetMinute());
696                        psiItem->FinishAction(tps.m_pgData.m_dwFinishAction);
697
698                        switch (tps.m_pgData.m_tType)
699                        {
700                        case Drive:
701                            psiItem->SetDrive(tps.m_pgData.m_strSelectedDrive);
702                            break;
703                        case Folder:
704                            psiItem->SetFolder(tps.m_pgData.m_strFolder);
705                            psiItem->RemoveFolder(tps.m_pgData.m_bRemoveFolder);
706                            psiItem->Subfolders(tps.m_pgData.m_bSubfolders);
707                            psiItem->OnlySubfolders(tps.m_pgData.m_bRemoveOnlySub);
708                            break;
709                        case File:
710                            psiItem->SetFile(tps.m_pgData.m_strFile);
711                            psiItem->UseWildcards(tps.m_pgData.m_bUseWildCards);
712                            psiItem->WildcardsInSubfolders(tps.m_pgData.m_bWildCardsInSubfolders);
713                            break;
714                        default:
715                            NODEFAULT;
716                        };
717
718                        CString strTmp;
719                        psiItem->GetData(strTmp);
720
721                        if (strTmp != strData)
722                        {
723                            // data has changed -> reset statistics
724
725                            psiItem->GetStatistics()->Reset();
726
727                            COleDateTime odt;
728                            odt.SetStatus(COleDateTime::null);
729
730                            psiItem->SetLastTime(odt);
731                        }
732
733                        psiItem->CalcNextTime();
734
735                        if (!SetTimer(psiItem->m_uTimerID, psiItem->GetTimeSpan(), NULL))
736                        {
737                            AfxTimeOutMessageBox(IDS_ERROR_TIMER, MB_ICONERROR);
738
739                            if (pDoc->m_bLog)
740                                pDoc->LogAction(IDS_ERROR_TIMER);
741                        }
742
743                //Update Reboot Part
744                if (tps.m_pgSchedule.m_iWhen == Reboot) 
745                {
746                //Here we are setting the appropriate entry into the Registry Key :
747                //HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
748                //The entry should be in Name - Data pair, where Name is the name of the application and Data is the path of the executable
749                    CKey kReg;
750                    CString m_strExePath;
751                    CString m_strName;
752                    char Fullname[260];
753                    char Filename[260];
754                    char Extension[5];
755                    char Pathname[260];
756                    char myDrive[10];
757                    char *buffer = new char[260];
758
759                    if (kReg.Open(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run"))
760                    {
761                         GetModuleFileName(AfxGetInstanceHandle(),Fullname,sizeof Fullname);
762                        _splitpath(Fullname,myDrive,Pathname,Filename,Extension); 
763                        strcpy(buffer,myDrive);
764                        strncat(buffer,Pathname,250);
765                        strncpy(Pathname,buffer,260);
766                        delete buffer;
767                        m_strExePath = '"';
768                        //gt m_strExePath+=  CString(Pathname);
769                        m_strExePath+= "Eraserl.exe";
770                        m_strExePath+= '"';
771                       
772                        switch (tps.m_pgData.m_tType)
773                        {
774                            case Drive:
775                                m_strExePath+= " -disk " + tps.m_pgData.m_strSelectedDrive;
776                                break;
777                            case Folder:
778                                m_strExePath+= " -folder ";
779                                m_strExePath+= '"';
780                                m_strExePath+= tps.m_pgData.m_strFolder;
781                                m_strExePath+= '"';
782                                if (tps.m_pgData.m_bRemoveFolder==FALSE) {m_strExePath+= " -keepfolder ";}
783                                if (tps.m_pgData.m_bSubfolders) {m_strExePath+= " -subfolders ";}
784                                break;
785                            case File:
786                                m_strExePath+= " -file ";
787                                m_strExePath+= '"';
788                                m_strExePath+= tps.m_pgData.m_strFile;
789                                m_strExePath+= '"';
790                                break;
791                            default:
792                                NODEFAULT;
793                        };
794                        kReg.SetValue(m_strExePath,psiItem->GetId());
795                        m_strExePath.ReleaseBuffer();
796                        kReg.Close();
797                    }
798                }
799//                     
800                        UpdateList();
801                       
802                        LibrarySettings* plsTmp1 = tps.m_pPageFileMethodOptions->GetLibSettings();
803                        psiItem->m_bMethod = plsTmp1->m_nFileMethodID;
804                        psiItem->m_uEraseItems = plsTmp1->m_uItems;
805                        psiItem->m_nRndPass = plsTmp1->m_nFileRandom;
806                        plsTmp1->m_nFileMethodID = plsTmp.m_nFileMethodID;
807                        plsTmp1->m_nFileRandom = plsTmp.m_nFileRandom;
808                        plsTmp1->m_uItems = plsTmp.m_uItems;
809                        saveLibrarySettings(plsTmp1);   
810
811                        pDoc->CalcNextAssignment();
812                        pDoc->UpdateToolTip();
813                        pDoc->SaveTasksToDefault(); 
814
815                                       
816
817                    }
818                   
819                }
820            }
821        }
822    }
823    catch (CException *e)
824    {
825        ASSERT(FALSE);
826        REPORT_ERROR(e);
827        e->Delete();
828    }
829}
830
831void CSchedulerView::OnTimer(UINT_PTR nIDEvent)
832{
833    TRACE("CSchedulerView::OnTimer\n");
834    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
835    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
836
837    try
838    {
839        INT_PTR iSize = pDoc->m_paScheduledTasks.GetSize();
840        CScheduleItem *psiItem = 0;
841
842        while (iSize--)
843        {
844            psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iSize]);
845            if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)) & !(psiItem->GetSchedule() == Reboot))
846            {
847                if (psiItem->m_uTimerID == nIDEvent)
848                {
849                    KillTimer(psiItem->m_uTimerID);
850
851                    if (!pDoc->m_bSchedulerEnabled)
852                    {
853                        // Scheduler not active at the moment, just
854                        // calculate the next time
855
856                        psiItem->CalcNextTime();
857
858                        if (!SetTimer(psiItem->m_uTimerID, psiItem->GetTimeSpan(), NULL))
859                        {
860                            if (!pDoc->m_bNoVisualErrors)
861                                AfxTimeOutMessageBox(IDS_ERROR_TIMER, MB_ICONERROR);
862
863                            if (pDoc->m_bLog)
864                                pDoc->LogAction(IDS_ERROR_TIMER);
865                        }
866
867                        UpdateList();
868                        pDoc->CalcNextAssignment();
869                    }
870                    else
871                    {
872                        if (psiItem->IsRunning() || psiItem->IsQueued() || !psiItem->ScheduledNow())
873                        {
874                            // thread still running, queued or is not due anytime soon,
875                            // skip procedure and calculate next time
876
877                            psiItem->CalcNextTime();
878
879                            if (!SetTimer(psiItem->m_uTimerID, psiItem->GetTimeSpan(), NULL))
880                            {
881                                if (!pDoc->m_bNoVisualErrors)
882                                    AfxTimeOutMessageBox(IDS_ERROR_TIMER, MB_ICONERROR);
883
884                                if (pDoc->m_bLog)
885                                    pDoc->LogAction(IDS_ERROR_TIMER);
886                            }
887                        }
888                        else if (pDoc->m_bQueueTasks)
889                        {
890                            counterLock();
891
892                            if (pDoc->m_wProcessCount > 0)
893                            {
894                                QueueTask(psiItem);
895                                UpdateList();
896                                counterUnlock();
897                            }
898                            else
899                            {
900                                counterUnlock();
901                                RunScheduledTask(psiItem);
902                            }
903                        }
904                        else
905                        {
906                            RunScheduledTask(psiItem);
907                        }
908                    } // m_bEnabled
909
910                    pDoc->UpdateToolTip();
911                    return;
912                } // == nIDEvent
913            } // valid
914        }
915    }
916    catch (CException *e)
917    {
918        ASSERT(FALSE);
919        counterUnlock();
920
921        try
922        {
923            if (!pDoc->m_bNoVisualErrors)
924            {
925                TCHAR szError[255];
926                e->GetErrorMessage(szError, 255);
927                AfxTimeOutMessageBox(szError, MB_ICONERROR);
928            }
929
930            if (pDoc->m_bLog)
931                pDoc->LogException(e);
932        }
933        catch (...)
934        {
935        }
936
937        e->Delete();
938    }
939
940    // no such timer !? kill it anyway...
941    KillTimer(nIDEvent);
942
943    CFlatListView::OnTimer(nIDEvent);
944}
945
946LRESULT CSchedulerView::OnEraserNotify(WPARAM wParam, LPARAM)
947{
948    TRACE("CSchedulerView::OnEraserNotify\n");
949
950    switch (wParam)
951    {
952    case ERASER_WIPE_BEGIN:
953        EraserWipeBegin();
954        break;
955    case ERASER_WIPE_UPDATE:
956        EraserWipeUpdate();
957        break;
958    case ERASER_WIPE_DONE:
959        EraserWipeDone();
960        break;
961    }
962
963    return TRUE;
964}
965
966BOOL CSchedulerView::EraserWipeDone()
967{
968    TRACE("CSchedulerView::EraserWipeDone\n");
969
970    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
971    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
972
973    try
974    {
975        INT_PTR iSize = pDoc->m_paScheduledTasks.GetSize();
976        CScheduleItem *psiItem = 0;
977
978        while (iSize--)
979        {
980            psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iSize]);
981            if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
982            {
983                // if thread has been running lately but has stopped since.
984                // that is, we have not destroyed the context yet
985
986                if (eraserOK(eraserIsValidContext(psiItem->m_ehContext)) && !psiItem->IsRunning())
987                {
988                    E_UINT8 uValue = 0;
989                    COleDateTime odt = GetTimeTimeZoneBased();
990                    psiItem->SetLastTime(odt);
991
992                    // not completed
993                    if (eraserOK(eraserCompleted(psiItem->m_ehContext, &uValue)) && !uValue)
994                    {
995                        // not terminated
996                        if (eraserOK(eraserTerminated(psiItem->m_ehContext, &uValue)) && !uValue)
997                        {
998                            // --> failed
999                            if (pDoc->m_bLog)
1000                            {
1001                                CString str, strData;
1002                                psiItem->GetData(strData);
1003
1004                                AfxFormatString1(str, IDS_ACTION_ERROR, strData);
1005                                pDoc->LogAction(str);
1006
1007                                // log failed items
1008                                E_UINT32 uFailed = 0;
1009                                E_UINT16 uErrors = 0, uSize = 0;
1010                                eraserFailedCount(psiItem->m_ehContext, &uFailed);
1011                                eraserErrorStringCount(psiItem->m_ehContext, &uErrors);
1012
1013                                if (uErrors > 0)
1014                                {
1015                                    for (E_UINT16 uIndex = 0; uIndex < uErrors; uIndex++)
1016                                    {
1017                                        if (eraserOK(eraserErrorString(psiItem->m_ehContext, uIndex, 0, &uSize)))
1018                                        {
1019                                            if (eraserOK(eraserErrorString(psiItem->m_ehContext, uIndex,
1020                                                    (LPVOID)strData.GetBuffer((int)uSize), &uSize)))
1021                                            {
1022                                                strData.ReleaseBuffer();
1023                                                pDoc->LogAction(strData);
1024                                            }
1025                                            else
1026                                                strData.ReleaseBuffer();
1027                                        }
1028                                    }
1029                                }
1030
1031                                if (uFailed > 0)
1032                                {
1033                                    UINT nError;
1034
1035                                    if (psiItem->GetType() == Drive)
1036                                        nError = IDS_ACTION_ERROR_UNUSED;
1037                                    else
1038                                        nError = IDS_ACTION_ERROR_FILE;
1039
1040                                    for (E_UINT32 uIndex = 0; uIndex < uFailed; uIndex++)
1041                                    {
1042                                        if (eraserOK(eraserFailedString(psiItem->m_ehContext, uIndex, 0, &uSize)))
1043                                        {
1044                                            if (eraserOK(eraserFailedString(psiItem->m_ehContext, uIndex,
1045                                                    (LPVOID)strData.GetBuffer((int)uSize), &uSize)))
1046                                            {
1047                                                strData.ReleaseBuffer();
1048                                                AfxFormatString1(str, nError, strData);
1049                                                pDoc->LogAction(str);
1050                                            }
1051                                            else
1052                                                strData.ReleaseBuffer();
1053                                        }
1054                                    }
1055                                }
1056                            } // m_bLog
1057
1058                            // update task statistics
1059                            psiItem->UpdateStatistics();
1060                        }
1061                    } // Done
1062                    else
1063                    {
1064                        if (pDoc->m_bLog && !pDoc->m_bLogOnlyErrors)
1065                        {
1066                            CString str, strData;
1067                            psiItem->GetData(strData);
1068
1069                            AfxFormatString1(str, IDS_ACTION_DONE, strData);
1070                            pDoc->LogAction(str);
1071                        }
1072
1073                        // update task statistics
1074                        psiItem->UpdateStatistics();
1075                        psiItem->GetStatistics()->m_dwTimesSuccess++;
1076                    }
1077
1078                    // remove folders
1079
1080                    if (psiItem->GetType() == Folder && psiItem->RemoveFolder())
1081                    {
1082                        CString strFolder;
1083                        CStringArray saFiles, saFolders;
1084
1085                        psiItem->GetData(strFolder);
1086
1087                        parseDirectory((LPCTSTR)strFolder,
1088                            saFiles,
1089                            saFolders,
1090                            psiItem->Subfolders());
1091
1092                        if (psiItem->OnlySubfolders())
1093                        {
1094                            // remove the last folder from the list,
1095                            // since the user wishes it would not be
1096                            // removed
1097
1098                            if (saFolders.GetSize() > 0)
1099                                saFolders.SetSize(saFolders.GetSize() - 1);
1100                        }
1101
1102                        INT_PTR iSize = saFolders.GetSize();
1103                        if (iSize > 0)
1104                        {
1105                            for (int i = 0; i < iSize; i++)
1106                            {
1107                                if (eraserOK(eraserRemoveFolder((LPVOID)(LPCTSTR)saFolders[i],
1108                                        (E_UINT16)saFolders[i].GetLength(), ERASER_REMOVE_FOLDERONLY)))
1109                                {
1110                                    SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, (LPCTSTR)saFolders[i], NULL);
1111                                }
1112                            }
1113
1114                            saFolders.RemoveAll();
1115                        }
1116                    }
1117
1118                    uValue = 0;
1119                    eraserTerminated(psiItem->m_ehContext, &uValue);
1120
1121                    counterLock();
1122
1123                    if (!uValue && pDoc->m_wProcessCount > 0)
1124                        pDoc->m_wProcessCount--;
1125
1126                    counterUnlock();
1127
1128                    // destroy context
1129                    VERIFY(eraserOK(eraserDestroyContext(psiItem->m_ehContext)));
1130                    psiItem->m_ehContext = ERASER_INVALID_CONTEXT;
1131
1132                } // not running
1133            } // valid
1134        }
1135
1136        // run possible queued tasks
1137        psiItem = GetNextQueuedTask();
1138
1139        if (psiItem)
1140            RunScheduledTask(psiItem);
1141
1142        UpdateList();
1143        pDoc->CalcNextAssignment();
1144        pDoc->UpdateToolTip();
1145
1146        return TRUE;
1147    }
1148    catch (CException *e)
1149    {
1150        ASSERT(FALSE);
1151        counterUnlock();
1152
1153        try
1154        {
1155            if (pDoc->m_bLog)
1156                pDoc->LogException(e);
1157        }
1158        catch (...)
1159        {
1160        }
1161
1162        e->Delete();
1163    }
1164
1165    return FALSE;
1166}
1167
1168BOOL CSchedulerView::EraserWipeBegin()
1169{
1170    TRACE("CSchedulerView::EraserWipeBegin\n");
1171
1172    if (IsWindowVisible())
1173    {
1174        CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1175        ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1176
1177        try
1178        {
1179            CListCtrl&      lc          = GetListCtrl();
1180            int             iCount      = lc.GetItemCount();
1181            INT_PTR         iIndex      = 0;
1182            CScheduleItem   *psiItem    = 0;
1183            CString         str;
1184            CString         strOld;
1185
1186            str.LoadString(IDS_INFO_RUNNING);
1187
1188            // update information for all active threads
1189            for (int iItem = 0; iItem < iCount; iItem++)
1190            {
1191                iIndex = lc.GetItemData(iItem);
1192
1193                if (iIndex >= 0 && iIndex < pDoc->m_paScheduledTasks.GetSize())
1194                {
1195                    psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iIndex]);
1196                    if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1197                    {
1198                        if (psiItem->IsRunning())
1199                        {
1200                            strOld = lc.GetItemText(iItem, 3);
1201
1202                            if (str.CompareNoCase(strOld) != 0)
1203                            {
1204                                SetRedraw(FALSE);
1205                                lc.SetItemText(iItem, 3, (LPCTSTR)str);
1206                                SetRedraw(TRUE);
1207                            }
1208                        }
1209                    }
1210                }
1211            }
1212
1213            pDoc->UpdateToolTip();
1214
1215            return TRUE;
1216        }
1217        catch (CException *e)
1218        {
1219            ASSERT(FALSE);
1220
1221            try
1222            {
1223                if (pDoc->m_bLog)
1224                    pDoc->LogException(e);
1225            }
1226            catch (...)
1227            {
1228            }
1229
1230            e->Delete();
1231        }
1232    }
1233
1234    return FALSE;
1235}
1236
1237BOOL CSchedulerView::EraserWipeUpdate()
1238{
1239    TRACE("CSchedulerView::EraserWipeUpdate\n");
1240
1241    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1242    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1243
1244    CListCtrl&  lc              = GetListCtrl();
1245    BOOL        bSetProgress    = FALSE;
1246
1247    if (IsWindowVisible())
1248    {
1249        SetRedraw(FALSE);
1250
1251        int             iCount      = lc.GetItemCount();
1252        DWORD_PTR       iIndex      = 0;
1253        CScheduleItem   *psiItem    = 0;
1254        CString         str;
1255        CString         strOld;
1256        CString         strFormat;
1257
1258        try
1259        {
1260            // update information for all active threads
1261            for (int iItem = 0; iItem < iCount; iItem++)
1262            {
1263                iIndex = lc.GetItemData(iItem);
1264
1265                if (iIndex >= 0 && iIndex < pDoc->m_paScheduledTasks.GetSize())
1266                {
1267                    psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iIndex]);
1268                    if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1269                    {
1270                        if (psiItem->IsRunning())
1271                        {
1272                            // if only one task (us) is selected, show the progress
1273                            // bar on the status bar
1274
1275                            if (lc.GetSelectedCount() == 1 &&
1276                                lc.GetItemState(iItem, LVIS_SELECTED) == LVIS_SELECTED)
1277                            {
1278                                TCHAR szValue[255];
1279                                E_UINT16 uSize = 255;
1280                                E_UINT8 uValue = 0;
1281
1282                                if (eraserOK(eraserProgGetTotalPercent(psiItem->m_ehContext, &uValue)))
1283                                    m_pbProgress.SetPos(uValue);
1284
1285                                if (eraserOK(eraserProgGetMessage(psiItem->m_ehContext, (LPVOID)szValue, &uSize)))
1286                                    m_pbProgress.SetText((LPCTSTR)szValue);
1287
1288                                bSetProgress = TRUE;
1289                            }
1290                        } // running
1291                    }
1292                }
1293            }
1294        }
1295        catch (CException *e)
1296        {
1297            ASSERT(FALSE);
1298
1299            try
1300            {
1301                if (pDoc->m_bLog)
1302                    pDoc->LogException(e);
1303            }
1304            catch (...)
1305            {
1306            }
1307
1308            e->Delete();
1309        }
1310
1311        SetRedraw(TRUE);
1312    }
1313
1314    // if there were no tasks selected, or the selected task
1315    // was not running, or the Scheduler window is not visible,
1316    // remove the progress bar
1317
1318    if (!bSetProgress && m_pbProgress.IsWindowVisible())
1319        m_pbProgress.Clear();
1320
1321    pDoc->UpdateToolTip();
1322
1323    return TRUE;
1324}
1325
1326
1327void CSchedulerView::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* /*pHint*/)
1328{
1329    TRACE("CSchedulerView::OnUpdate\n");
1330
1331    if (lHint == SCHEDULER_SET_TIMERS)
1332    {
1333        SetTimers();
1334        lHint = 0L;
1335    }
1336
1337    if (lHint == 0L)
1338    {
1339        CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1340        ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1341
1342        try
1343        {
1344            UpdateList();
1345            pDoc->CalcNextAssignment();
1346            pDoc->UpdateToolTip();
1347        }
1348        catch (...)
1349        {
1350            ASSERT(FALSE);
1351        }
1352    }
1353}
1354
1355void CSchedulerView::OnDestroy()
1356{
1357    TRACE("CSchedulerView::OnDestroy\n");
1358
1359    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1360
1361    if (AfxIsValidAddress(pDoc, sizeof(CEraserDoc)))
1362    {
1363        try
1364        {
1365            CScheduleItem *psiItem = 0;
1366            INT_PTR iSize = pDoc->m_paScheduledTasks.GetSize();
1367
1368            while (iSize--)
1369            {
1370                psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iSize]);
1371                if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1372                    KillTimer(psiItem->m_uTimerID);
1373            }
1374        }
1375        catch (CException *e)
1376        {
1377            ASSERT(FALSE);
1378
1379            if (pDoc->m_bLog)
1380                pDoc->LogException(e);
1381
1382            e->Delete();
1383        }
1384    }
1385
1386    CFlatListView::OnDestroy();
1387}
1388
1389BOOL CSchedulerView::SetTimers()
1390{
1391    TRACE("CSchedulerView::SetTimers\n");
1392
1393    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1394    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1395
1396    try
1397    {
1398        CScheduleItem *psiItem = 0;
1399        INT_PTR iSize = pDoc->m_paScheduledTasks.GetSize();
1400
1401        while (iSize--)
1402        {
1403            psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iSize]);
1404            if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1405            {
1406                if (psiItem->m_uTimerID > 0)
1407                    KillTimer(psiItem->m_uTimerID);
1408
1409                psiItem->m_uTimerID = GetNextTimerID();
1410
1411                if (!psiItem->StillValid())
1412                    psiItem->CalcNextTime();
1413
1414                if (!SetTimer(psiItem->m_uTimerID, psiItem->GetTimeSpan(), NULL))
1415                {
1416                    AfxTimeOutMessageBox(IDS_ERROR_TIMER, MB_ICONERROR);
1417
1418                    if (pDoc->m_bLog)
1419                        pDoc->LogAction(IDS_ERROR_TIMER);
1420
1421                    return FALSE;
1422                }
1423            }
1424        }
1425
1426        return TRUE;
1427    }
1428    catch (CException *e)
1429    {
1430        ASSERT(FALSE);
1431
1432        try
1433        {
1434            if (pDoc->m_bLog)
1435                pDoc->LogException(e);
1436        }
1437        catch (...)
1438        {
1439        }
1440
1441        e->Delete();
1442    }
1443
1444    return FALSE;
1445}
1446
1447void CSchedulerView::UpdateList()
1448{
1449    TRACE("CSchedulerView::UpdateList\n");
1450
1451    SetRedraw(FALSE);
1452
1453    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1454    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1455
1456    try
1457    {
1458        CListCtrl& lc = GetListCtrl();
1459        CUIntArray uaSelected;
1460
1461        // get selected items
1462        POSITION pos = lc.GetFirstSelectedItemPosition();
1463        while (pos) uaSelected.Add((UINT)lc.GetNextSelectedItem(pos));
1464
1465        lc.DeleteAllItems();
1466
1467        CScheduleItem *psiItem = 0;
1468        INT_PTR iSize = 0;
1469        int iItem = 0;
1470
1471        // item information
1472        CString strData;
1473        COleDateTime odtLast;
1474
1475        BOOL bExists = FALSE;
1476        WIN32_FIND_DATA findFileData;
1477        HANDLE hFind = NULL;
1478        SHFILEINFO sfi;
1479
1480        LV_ITEM lvi;
1481        ZeroMemory(&lvi, sizeof(LV_ITEM));
1482
1483        // remove the progress bar from the window
1484        m_pbProgress.Clear();
1485
1486        // clean invalid objects from the task list
1487        pDoc->CleanList(pDoc->m_paScheduledTasks, sizeof(CScheduleItem));
1488        iSize = pDoc->m_paScheduledTasks.GetSize();
1489
1490        // populate the list
1491        while (iSize--)
1492        {
1493            psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[iSize]);
1494            ASSERT(AfxIsValidAddress(psiItem, sizeof(CScheduleItem)));
1495
1496            psiItem->GetData(strData);
1497
1498            SHGetFileInfo((LPCTSTR)strData,
1499                      0,
1500                      &sfi,
1501                      sizeof(SHFILEINFO),
1502                      SHGFI_SYSICONINDEX |
1503                      SHGFI_SMALLICON |
1504                      SHGFI_TYPENAME |
1505                      SHGFI_DISPLAYNAME);
1506
1507            switch (psiItem->GetType())
1508            {
1509            case File:
1510                if (psiItem->UseWildcards())
1511                {
1512                    bExists = FALSE;
1513                    break;
1514                }
1515                // no break!
1516            case Folder:
1517                {
1518                    if (strData.GetLength() <= _MAX_DRIVE &&
1519                        strData.Find(":\\") == 1)
1520                    {
1521                        // clear all data on a drive!
1522                        bExists = TRUE;
1523                    }
1524                    else
1525                    {
1526                        // file information
1527
1528                        if (strData.GetLength()&&strData[strData.GetLength() - 1] == '\\')
1529                            strData = strData.Left(strData.GetLength() - 1);
1530
1531                        hFind = FindFirstFile((LPCTSTR)strData, &findFileData);
1532
1533                        bExists = (hFind != INVALID_HANDLE_VALUE);
1534
1535                        if (bExists)
1536                            VERIFY(FindClose(hFind));
1537                    }
1538
1539                    psiItem->GetData(strData);
1540                }
1541                break;
1542            case Drive:
1543                bExists = TRUE;
1544                if (strData == DRIVE_ALL_LOCAL)
1545                {
1546                    SHGetFileInfo((LPCTSTR)"C:\\",
1547                                  0,
1548                                  &sfi,
1549                                  sizeof(SHFILEINFO),
1550                                  SHGFI_SYSICONINDEX |
1551                                  SHGFI_SMALLICON |
1552                                  SHGFI_TYPENAME |
1553                                  SHGFI_DISPLAYNAME);
1554                }
1555                break;
1556            default:
1557                NODEFAULT;
1558            }
1559
1560            // name
1561
1562            lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
1563
1564            lvi.iImage = (bExists) ? sfi.iIcon : -1;
1565            lvi.iItem = iItem;
1566            lvi.lParam = iSize;
1567            lvi.iSubItem = ColumnName;
1568
1569            if (psiItem->GetType() == Drive)
1570            {
1571                if (strData == DRIVE_ALL_LOCAL)
1572                    strData = szLocalDrives;
1573                else
1574                    strData = sfi.szDisplayName;
1575            }
1576
1577            lvi.pszText = strData.GetBuffer(strData.GetLength());
1578            lvi.iItem = lc.InsertItem(&lvi);
1579
1580            strData.ReleaseBuffer();
1581
1582            // type
1583
1584            lvi.mask = LVIF_TEXT;
1585            lvi.iSubItem = ColumnType;
1586
1587            if (psiItem->GetType() == Drive)
1588                strData = "Unused disk space";
1589            else if (psiItem->UseWildcards())
1590                strData = "Wildcard search";
1591            else
1592                strData = sfi.szTypeName;
1593
1594            lvi.pszText = strData.GetBuffer(strData.GetLength());
1595            lc.SetItem(&lvi);
1596
1597            strData.ReleaseBuffer();
1598
1599            // last run
1600
1601            lvi.iSubItem = ColumnLast;
1602
1603            odtLast = psiItem->GetLastTime();
1604
1605            if (odtLast.GetStatus() == COleDateTime::valid)
1606                strData = odtLast.Format("%c");
1607            else
1608                strData.Empty();
1609
1610            lvi.pszText = strData.GetBuffer(strData.GetLength());
1611            lc.SetItem(&lvi);
1612
1613            strData.ReleaseBuffer();
1614
1615            // next run
1616
1617            lvi.iSubItem = ColumnNext;
1618
1619            if (psiItem->IsRunning())
1620            {
1621                try
1622                {
1623                    strData.LoadString(IDS_INFO_RUNNING);
1624                }
1625                catch (CException *e)
1626                {
1627                    ASSERT(FALSE);
1628                    strData.Empty();
1629
1630                    if (pDoc->m_bLog)
1631                        pDoc->LogException(e);
1632
1633                    e->Delete();
1634                }
1635            }
1636            else if (psiItem->IsQueued())
1637            {
1638                try
1639                {
1640                    strData.LoadString(IDS_INFO_QUEUED);
1641                }
1642                catch (CException *e)
1643                {
1644                    ASSERT(FALSE);
1645                    strData.Empty();
1646
1647                    if (pDoc->m_bLog)
1648                        pDoc->LogException(e);
1649
1650                    e->Delete();
1651                }
1652            }
1653            else
1654            {
1655                strData = psiItem->GetNextTime().Format("%c");
1656            }
1657
1658            lvi.pszText = strData.GetBuffer(strData.GetLength());
1659            lc.SetItem(&lvi);
1660
1661            strData.ReleaseBuffer();
1662
1663            // schedule
1664
1665            lvi.iSubItem = ColumnSchedule;
1666
1667            strData = "Every ";
1668            strData += szScheduleName[psiItem->GetSchedule()];
1669
1670            lvi.pszText = strData.GetBuffer(strData.GetLength());
1671            lc.SetItem(&lvi);
1672
1673            strData.ReleaseBuffer();
1674
1675            iItem++;
1676        }
1677
1678        // set previously selected items as selected again
1679        int iListCount = lc.GetItemCount();
1680        int iSelectItem = -1;
1681
1682        iSize = uaSelected.GetSize();
1683        for (iItem = 0; iItem < iSize; iItem++)
1684        {
1685            iSelectItem = (int)uaSelected[iItem];
1686
1687            if (iSelectItem < iListCount)
1688                SelItemRange(TRUE, iSelectItem, iSelectItem);
1689        }
1690    }
1691    catch (...)
1692    {
1693        ASSERT(FALSE);
1694    }
1695
1696    SetRedraw(TRUE);
1697}
1698
1699void CSchedulerView::OnLButtonDblClk(UINT /*nFlags*/, CPoint /*point*/)
1700{
1701    TRACE("CSchedulerView::OnLButtonDblClk\n");
1702    OnEditProperties();
1703}
1704
1705void CSchedulerView::OnUpdateProcessRun(CCmdUI* pCmdUI)
1706{
1707    CListCtrl& lc = GetListCtrl();
1708    pCmdUI->Enable(lc.GetSelectedCount() > 0);
1709}
1710
1711void CSchedulerView::OnUpdateProcessRunAll(CCmdUI* pCmdUI)
1712{
1713    CListCtrl& lc = GetListCtrl();
1714    pCmdUI->Enable(lc.GetItemCount() > 0);
1715}
1716
1717void CSchedulerView::OnProcessRun()
1718{
1719    TRACE("CSchedulerView::OnProcessRun\n");
1720
1721    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1722    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1723
1724    try
1725    {
1726        CListCtrl& lc = GetListCtrl();
1727
1728        if (lc.GetSelectedCount() > 0)
1729        {
1730            int nItem;
1731            INT_PTR nIndex;
1732            POSITION pos = lc.GetFirstSelectedItemPosition();
1733            BOOL bQueued = FALSE;
1734            CScheduleItem *psiItem = 0;
1735
1736            while (pos)
1737            {
1738                nItem = lc.GetNextSelectedItem(pos);
1739                nIndex = lc.GetItemData(nItem);
1740
1741                if (nIndex >= 0 && nIndex < pDoc->m_paScheduledTasks.GetSize())
1742                {
1743                    psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[nIndex]);
1744                    if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1745                    {
1746                        if (psiItem->IsRunning())
1747                        {
1748                            // thread still running, skip procedure
1749                            continue;
1750                        }
1751                        else if (pDoc->m_bQueueTasks)
1752                        {
1753                            counterLock();
1754
1755                            if (pDoc->m_wProcessCount > 0)
1756                            {
1757                                QueueTask(psiItem);
1758                                bQueued = TRUE;
1759                                counterUnlock();
1760                            }
1761                            else
1762                            {
1763                                counterUnlock();
1764                                RunScheduledTask(psiItem);
1765                            }
1766                        }
1767                        else
1768                        {
1769                            RunScheduledTask(psiItem);
1770                        }
1771                    }
1772                }
1773            }
1774
1775            if (bQueued) UpdateList();
1776        }
1777    }
1778    catch (CException *e)
1779    {
1780        ASSERT(FALSE);
1781        counterUnlock();
1782
1783        try
1784        {
1785            if (!pDoc->m_bNoVisualErrors)
1786            {
1787                TCHAR szError[255];
1788                e->GetErrorMessage(szError, 255);
1789                AfxTimeOutMessageBox(szError, 255);
1790            }
1791
1792            if (pDoc->m_bLog)
1793                pDoc->LogException(e);
1794        }
1795        catch (...)
1796        {
1797        }
1798
1799        e->Delete();
1800    }
1801}
1802
1803void CSchedulerView::OnProcessRunAll()
1804{
1805    if (AfxMessageBox(IDS_QUESTION_RUNALL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, 0) == IDYES)
1806    {
1807        SelItemRange(TRUE, 0, -1);
1808        OnProcessRun();
1809    }
1810}
1811
1812
1813void CSchedulerView::OnUpdateProcessStop(CCmdUI* pCmdUI)
1814{
1815    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1816    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1817
1818    try
1819    {
1820        CListCtrl& lc = GetListCtrl();
1821
1822        if (lc.GetSelectedCount() == 1 && pDoc->m_wProcessCount > 0)
1823        {
1824            POSITION pos = lc.GetFirstSelectedItemPosition();
1825
1826            int       nItem = lc.GetNextSelectedItem(pos);
1827            DWORD_PTR nIndex = lc.GetItemData(nItem);
1828
1829            if (nIndex >= 0 && nIndex < pDoc->m_paScheduledTasks.GetSize())
1830            {
1831                CScheduleItem *psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[nIndex]);
1832                if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1833                {
1834                    if (psiItem->IsRunning() || psiItem->IsQueued())
1835                    {
1836                        pCmdUI->Enable();
1837                        return;
1838                    }
1839                }
1840            }
1841        }
1842    }
1843    catch (...)
1844    {
1845        ASSERT(FALSE);
1846    }
1847
1848    pCmdUI->Enable(FALSE);
1849}
1850
1851void CSchedulerView::OnProcessStop()
1852{
1853    TRACE("CSchedulerView::OnProcessStop\n");
1854
1855    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1856    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1857
1858    try
1859    {
1860        CListCtrl& lc = GetListCtrl();
1861
1862        counterLock();
1863
1864        if (lc.GetSelectedCount() == 1 && pDoc->m_wProcessCount > 0)
1865        {
1866            POSITION pos = lc.GetFirstSelectedItemPosition();
1867
1868            int nItem = lc.GetNextSelectedItem(pos);
1869            INT_PTR nIndex = lc.GetItemData(nItem);
1870
1871            if (nIndex >= 0 && nIndex < pDoc->m_paScheduledTasks.GetSize())
1872            {
1873                CScheduleItem *psiItem = static_cast<CScheduleItem*>(pDoc->m_paScheduledTasks[nIndex]);
1874                if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1875                {
1876                    if (psiItem->IsQueued())
1877                    {
1878                        RemoveTaskFromQueue(psiItem);
1879                        UpdateList();
1880                    }
1881                    else
1882                    {
1883                        counterUnlock();
1884                        TerminateThread(psiItem);
1885                        return;
1886                    }
1887                }
1888            }
1889        }
1890
1891        counterUnlock();
1892    }
1893    catch (CException *e)
1894    {
1895        ASSERT(FALSE);
1896        counterUnlock();
1897
1898        try
1899        {
1900            if (!pDoc->m_bNoVisualErrors)
1901            {
1902                TCHAR szError[255];
1903                e->GetErrorMessage(szError, 255);
1904                AfxTimeOutMessageBox(szError, MB_ICONERROR);
1905            }
1906
1907            if (pDoc->m_bLog)
1908                pDoc->LogException(e);
1909        }
1910        catch (...)
1911        {
1912        }
1913
1914        e->Delete();
1915    }
1916}
1917
1918void CSchedulerView::OnUpdateItems(CCmdUI* pCmdUI)
1919{
1920    CListCtrl& lc = GetListCtrl();
1921
1922    CString str;
1923    int iCount = lc.GetItemCount();
1924
1925    str.Format("%u Task", iCount);
1926
1927    if (iCount != 1)
1928        str += "s";
1929
1930    pCmdUI->SetText((LPCTSTR)str);
1931    pCmdUI->Enable();
1932}
1933
1934void CSchedulerView::OnUpdateEditSelectAll(CCmdUI* pCmdUI)
1935{
1936    CListCtrl& lc = GetListCtrl();
1937    pCmdUI->Enable(lc.GetItemCount() > 0);
1938}
1939
1940void CSchedulerView::OnEditSelectAll()
1941{
1942    SelItemRange(TRUE, 0, -1);
1943}
1944
1945void CSchedulerView::OnEditRefresh()
1946{
1947    UpdateList();
1948}
1949
1950BOOL CSchedulerView::TerminateThread(CScheduleItem *psiItem)
1951{
1952    // terminates the thread of a scheduled task
1953
1954    if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
1955    {
1956        try
1957        {
1958            if (psiItem->IsRunning())
1959            {
1960                CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
1961                ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
1962
1963                CWaitCursor wait;
1964
1965                eraserDestroyContext(psiItem->m_ehContext);
1966                psiItem->m_ehContext = ERASER_INVALID_CONTEXT;
1967
1968                // decrease process counter
1969                counterLock();
1970
1971                if (pDoc->m_wProcessCount > 0)
1972                    pDoc->m_wProcessCount--;
1973
1974                counterUnlock();
1975
1976                // log action if desired
1977                if (pDoc->m_bLog && !pDoc->m_bLogOnlyErrors)
1978                {
1979                    CString strAction, strData;
1980
1981                    psiItem->GetData(strData);
1982                    AfxFormatString1(strAction, IDS_ACTION_STOP, strData);
1983
1984                    pDoc->LogAction(strAction);
1985                }
1986
1987                // update task statistics
1988                psiItem->GetStatistics()->m_dwTimesInterrupted++;
1989            }
1990
1991            return TRUE;
1992        }
1993        catch (...)
1994        {
1995            counterUnlock();
1996            ASSERT(FALSE);
1997        }
1998    }
1999
2000    return FALSE;
2001}
2002E_UINT8 getMetodId(E_UINT8 old)
2003{
2004    E_UINT8 res = 0;
2005    old ^= 0x80;
2006    for(E_UINT8 i = 0; i < 5; i++)
2007        if (1 << i == old)
2008            res = i;
2009    return res;
2010}
2011
2012BOOL CSchedulerView::RunScheduledTask(CScheduleItem *psiItem)
2013{
2014    // starts a scheduled task
2015
2016    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
2017    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
2018
2019    try
2020    {
2021        CString strData;
2022        CStringArray saData;
2023        INT_PTR iSize = 0, i;
2024        BOOL bResult = FALSE;
2025
2026        // stop the timer
2027        KillTimer(psiItem->m_uTimerID);
2028
2029        // remove from queue
2030        RemoveTaskFromQueue(psiItem);
2031
2032        // just in case
2033        eraserDestroyContext(psiItem->m_ehContext);
2034        psiItem->m_ehContext = ERASER_INVALID_CONTEXT;
2035
2036        // create context
2037        if (eraserOK(eraserCreateContextEx(&psiItem->m_ehContext,/*(ERASER_METHOD)getMetodId(psiItem->m_bMethod)*/psiItem->m_bMethod,psiItem->m_nRndPass,psiItem->m_uEraseItems)))
2038        {
2039            // get data
2040            psiItem->GetData(strData);
2041
2042            // set parameters
2043            switch (psiItem->GetType())
2044            {
2045            case Drive:
2046                VERIFY(eraserOK(eraserSetDataType(psiItem->m_ehContext, ERASER_DATA_DRIVES)));
2047                if (strData == DRIVE_ALL_LOCAL)
2048                    GetLocalHardDrives(saData);
2049                else
2050                    saData.Add(strData);
2051
2052                iSize = saData.GetSize();
2053                for (i = 0; i < iSize; i++)
2054                {
2055                    VERIFY(eraserOK(eraserAddItem(psiItem->m_ehContext,
2056                        (LPVOID)(LPCTSTR)saData[i], (E_UINT16)saData[i].GetLength())));
2057                }
2058
2059                break;
2060            case Folder:
2061                {
2062                    CWaitCursor wait;
2063                    CStringArray saFolders;
2064
2065                    VERIFY(eraserOK(eraserSetDataType(psiItem->m_ehContext, ERASER_DATA_FILES)));
2066
2067                    parseDirectory((LPCTSTR)strData,
2068                                   saData,
2069                                   saFolders,
2070                                   psiItem->Subfolders());
2071
2072                    iSize = saData.GetSize();
2073                    for (i = 0; i < iSize; i++)
2074                    {
2075                        VERIFY(eraserOK(eraserAddItem(psiItem->m_ehContext,
2076                            (LPVOID)(LPCTSTR)saData[i], (E_UINT16)saData[i].GetLength())));
2077                    }
2078
2079                }
2080                break;
2081            case File:
2082                if (psiItem->UseWildcards())
2083                {
2084                    findMatchingFiles(strData, saData,
2085                                      psiItem->WildcardsInSubfolders());
2086//                  CString temp;
2087//                  for(int i = 0; i < saData.GetCount(); i++) {
2088//                      temp += saData[i];
2089//                      temp += "\n";
2090//                  }
2091//                  AfxMessageBox(temp);
2092//                  return false;
2093                }
2094                else
2095                    saData.Add(strData);
2096
2097                VERIFY(eraserOK(eraserSetDataType(psiItem->m_ehContext, ERASER_DATA_FILES)));
2098
2099                iSize = saData.GetSize();
2100                for (i = 0; i < iSize; i++)
2101                {
2102                    VERIFY(eraserOK(eraserAddItem(psiItem->m_ehContext,
2103                        (LPVOID)(LPCTSTR)saData[i], (E_UINT16)saData[i].GetLength())));
2104                }
2105                break;
2106            default:
2107                NODEFAULT;
2108            };
2109
2110            VERIFY(eraserOK(eraserSetWindow(psiItem->m_ehContext, GetSafeHwnd())));
2111            VERIFY(eraserOK(eraserSetWindowMessage(psiItem->m_ehContext, WM_ERASERNOTIFY)));
2112
2113            // start the thread
2114            bResult = eraserOK(eraserStart(psiItem->m_ehContext));
2115
2116            if (bResult)
2117            {
2118                // increase process counter
2119                counterLock();
2120                pDoc->m_wProcessCount++;
2121                counterUnlock();
2122
2123                // task statistics
2124                psiItem->GetStatistics()->m_dwTimes++;
2125                psiItem->CalcNextTime();
2126
2127                // log action
2128                if (pDoc->m_bLog && !pDoc->m_bLogOnlyErrors)
2129                {
2130                    CString strAction;
2131
2132                    AfxFormatString1(strAction, IDS_ACTION_RUN, strData);
2133                    pDoc->LogAction(strAction);
2134                }
2135            }
2136        }
2137
2138        // set timer for the next scheduled time
2139        if (!SetTimer(psiItem->m_uTimerID, psiItem->GetTimeSpan(), NULL))
2140        {
2141            if (!pDoc->m_bNoVisualErrors)
2142                AfxTimeOutMessageBox(IDS_ERROR_TIMER, MB_ICONERROR);
2143
2144            if (pDoc->m_bLog)
2145                pDoc->LogAction(IDS_ERROR_TIMER);
2146        }
2147
2148        return bResult;
2149    }
2150    catch (CException *e)
2151    {
2152        ASSERT(FALSE);
2153        counterUnlock();
2154
2155        try
2156        {
2157            if (!pDoc->m_bNoVisualErrors)
2158            {
2159                TCHAR szError[255];
2160                e->GetErrorMessage(szError, 255);
2161                AfxTimeOutMessageBox(szError, 255);
2162            }
2163
2164            if (pDoc->m_bLog)
2165                pDoc->LogException(e);
2166        }
2167        catch (...)
2168        {
2169        }
2170
2171        e->Delete();
2172    }
2173
2174    return FALSE;
2175}
2176
2177void CSchedulerView::QueueTask(CScheduleItem *psiItem)
2178{
2179    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
2180    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
2181
2182    try
2183    {
2184        if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
2185        {
2186            if (!psiItem->IsQueued() && !psiItem->IsRunning())
2187            {
2188                pDoc->m_paQueuedTasks.Add((LPVOID)psiItem);
2189                psiItem->SetQueued(TRUE);
2190            }
2191        }
2192    }
2193    catch (CException *e)
2194    {
2195        ASSERT(FALSE);
2196
2197        try
2198        {
2199            if (!pDoc->m_bNoVisualErrors)
2200            {
2201                TCHAR szError[255];
2202                e->GetErrorMessage(szError, 255);
2203                AfxTimeOutMessageBox(szError, 255);
2204            }
2205
2206            if (pDoc->m_bLog)
2207                pDoc->LogException(e);
2208        }
2209        catch (...)
2210        {
2211        }
2212
2213        e->Delete();
2214    }
2215}
2216
2217CScheduleItem* CSchedulerView::GetNextQueuedTask()
2218{
2219    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
2220    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
2221
2222    try
2223    {
2224        if (pDoc->m_paQueuedTasks.GetSize() > 0)
2225        {
2226            CScheduleItem *psiItem = static_cast<CScheduleItem*>(pDoc->m_paQueuedTasks.GetAt(0));
2227
2228            if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
2229                return psiItem;
2230            else
2231            {
2232                // remove this task from the list
2233                RemoveTaskFromQueue(psiItem);
2234
2235                // recursive... until we find one or there are no more
2236                // items on the list
2237                return GetNextQueuedTask();
2238            }
2239        }
2240    }
2241    catch (CException *e)
2242    {
2243        ASSERT(FALSE);
2244
2245        try
2246        {
2247            if (!pDoc->m_bNoVisualErrors)
2248            {
2249                TCHAR szError[255];
2250                e->GetErrorMessage(szError, 255);
2251                AfxTimeOutMessageBox(szError, 255);
2252            }
2253
2254            if (pDoc->m_bLog)
2255                pDoc->LogException(e);
2256        }
2257        catch (...)
2258        {
2259        }
2260
2261        e->Delete();
2262    }
2263
2264    return 0;
2265}
2266
2267void CSchedulerView::RemoveTaskFromQueue(CScheduleItem *psiItem)
2268{
2269    CEraserDoc *pDoc = static_cast<CEraserDoc*>(GetDocument());
2270    ASSERT(AfxIsValidAddress(pDoc, sizeof(CEraserDoc)));
2271
2272    try
2273    {
2274        if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
2275        {
2276            psiItem->SetQueued(FALSE);
2277
2278            CScheduleItem *psiCurrentItem = 0;
2279            INT_PTR iSize = pDoc->m_paQueuedTasks.GetSize();
2280
2281            while (iSize--)
2282            {
2283                psiCurrentItem = static_cast<CScheduleItem*>(pDoc->m_paQueuedTasks[iSize]);
2284
2285                if (psiCurrentItem == psiItem)
2286                {
2287                    pDoc->m_paQueuedTasks.RemoveAt(iSize);
2288                    pDoc->m_paQueuedTasks.FreeExtra();
2289                    break;
2290                }
2291            }
2292        }
2293
2294        pDoc->CleanList(pDoc->m_paQueuedTasks, sizeof(CScheduleItem));
2295    }
2296    catch (CException *e)
2297    {
2298        ASSERT(FALSE);
2299
2300        try
2301        {
2302            if (!pDoc->m_bNoVisualErrors)
2303            {
2304                TCHAR szError[255];
2305                e->GetErrorMessage(szError, 255);
2306                AfxTimeOutMessageBox(szError, 255);
2307            }
2308
2309            if (pDoc->m_bLog)
2310                pDoc->LogException(e);
2311        }
2312        catch (...)
2313        {
2314        }
2315
2316        e->Delete();
2317    }
2318}
Note: See TracBrowser for help on using the repository browser.