source: trunk/SchedulerView.cpp @ 841

Revision 841, 67.8 KB checked in by lowjoel, 6 years ago (diff)

-Implemented unique IDs for scheduled tasks.
-Store scheduled tasks under HKCU for better standard user support

Fixes #87.

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