source: trunk/EraserDoc.cpp @ 53

Revision 53, 36.4 KB checked in by lowjoel, 7 years ago (diff)

-Document the Schneider pass for eraser launcher
-More warning fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// EraserDoc.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 "resource.h"
25#include "Eraser.h"
26#include "Item.h"
27#include "EraserDll\EraserDll.h"
28#include "shared\key.h"
29#include "shared\utils.h"
30#include "PreferencesSheet.h"
31#include "EraserUI\TimeOutMessageBox.h"
32#include "EraserDoc.h"
33#include "MainFrm.h"
34#include "version.h"
35
36#include <direct.h>
37
38#ifdef _DEBUG
39#define new DEBUG_NEW
40#undef THIS_FILE
41static char THIS_FILE[] = __FILE__;
42#endif
43
44/////////////////////////////////////////////////////////////////////////////
45// CEraserDoc
46
47
48
49CString findRecycledBinGUID()
50{
51    const LPCTSTR RBIN_NSPACE = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace";
52    CKey kReg;
53    BOOL bRes;
54    HKEY hReg;
55    TCHAR szSubKey[MAX_KEY_LENGTH];
56    DWORD dwSubKeyLen = MAX_KEY_LENGTH;
57    DWORD dwIndex=0;
58    CString strValue=_T(""),strDef=_T(""),strFind=_T("");
59   
60    bRes = kReg.Open(HKEY_LOCAL_MACHINE,RBIN_NSPACE,FALSE);
61    hReg = kReg.GetHandle();
62    while (ERROR_SUCCESS == RegEnumKeyEx(hReg,dwIndex,szSubKey,&dwSubKeyLen,NULL,NULL,NULL,NULL))
63    {       
64        CKey kTmpReg;
65        CString strTmp=_T("");
66        strTmp.Format("%s\\%s", RBIN_NSPACE, szSubKey);
67        if (kTmpReg.Open(HKEY_LOCAL_MACHINE,strTmp,FALSE)) {
68            kTmpReg.GetValue(strValue,strDef,"");
69            if (strValue == "Recycle Bin") {
70                strFind = szSubKey; 
71            }
72            dwIndex++;
73            dwSubKeyLen = MAX_KEY_LENGTH;           
74        }
75        kTmpReg.Close();
76    }
77    kReg.Close();
78    return strFind;
79}
80
81
82IMPLEMENT_DYNCREATE(CEraserDoc, CDocument)
83
84BEGIN_MESSAGE_MAP(CEraserDoc, CDocument)
85    //{{AFX_MSG_MAP(CEraserDoc)
86    ON_UPDATE_COMMAND_UI(ID_FILE_EXPORT, OnUpdateFileExport)
87    ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
88    ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
89    ON_COMMAND(ID_TRAY_ENABLE, OnTrayEnable)
90    ON_UPDATE_COMMAND_UI(ID_TRAY_SHOW_WINDOW, OnUpdateTrayShowWindow)
91    ON_UPDATE_COMMAND_UI(ID_TRAY_ENABLE, OnUpdateTrayEnable)
92    ON_COMMAND(ID_TRAY_SHOW_WINDOW, OnTrayShowWindow)
93    ON_COMMAND(ID_EDIT_PREFERENCES_GENERAL, OnEditPreferencesGeneral)
94    ON_COMMAND(ID_EDIT_PREFERENCES_ERASER, OnEditPreferencesEraser)
95    ON_COMMAND(ID_FILE_VIEW_LOG, OnFileViewLog)
96    //}}AFX_MSG_MAP
97END_MESSAGE_MAP()
98
99/////////////////////////////////////////////////////////////////////////////
100// CEraserDoc construction/destruction
101
102CEraserDoc::CEraserDoc() :
103m_bResolveLock(TRUE),
104m_bResolveAskUser(TRUE),
105m_bSchedulerEnabled(TRUE),
106m_wProcessCount(0),
107m_bResultsForFiles(TRUE),
108m_bResultsForUnusedSpace(TRUE),
109m_bResultsOnlyWhenFailed(FALSE),
110m_bLog(TRUE),
111m_bLogOnlyErrors(FALSE),
112m_bStartup(TRUE),
113m_bQueueTasks(TRUE),
114m_bNoVisualErrors(FALSE),
115m_dwMaxLogSize(10),
116m_bClearSwap(FALSE),
117m_bShellextResults(FALSE),
118m_bErasextEnabled(TRUE),
119m_bEnableSlowPoll(FALSE),
120m_dwStartView((DWORD)-1),
121m_bIconAnimation(FALSE),
122m_bSmallIconView(FALSE),
123m_dwOutbarWidth(0),
124m_bNoTrayIcon(FALSE),
125m_bHideOnMinimize(FALSE),
126m_bViewInfoBar(FALSE),
127m_smallImageList (NULL)
128{
129    TRACE("CEraserDoc::CEraserDoc\n");
130
131    m_bAutoDelete = FALSE;
132    ZeroMemory(&m_rWindowRect, sizeof(RECT));
133
134    // find executable location for logging
135    try
136    {
137        // Create the Application Data path to store the Default ers file
138        if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, m_strAppDataPath.GetBuffer(MAX_PATH))))
139            AfxMessageBox("Could not determine path to Application Data", MB_ICONERROR);
140        m_strAppDataPath.ReleaseBuffer();
141        CreateDirectory((m_strAppDataPath += "\\") += szAppDataPath, NULL);
142
143        // read preferences
144        if (!ReadPreferences())
145        {
146            AfxTimeOutMessageBox(IDS_ERROR_PREFERENCES_READ, MB_ICONERROR);
147
148            if (m_bLog)
149                LogAction(IDS_ERROR_PREFERENCES_READ);
150        }
151
152        // create task bar tray icon
153        m_stIcon.Create(NULL, WM_TRAY_NOTIFY, "Starting...",
154                        AfxGetApp()->LoadIcon(IDI_ICON_TRAY),
155                        IDR_MENU_TRAY, !m_bNoTrayIcon);
156       
157        // create timers
158        CalcNextAssignment();
159        UpdateToolTip();
160
161        if (m_bLog && !m_bLogOnlyErrors)
162        {
163            CString strStart;
164            AfxFormatString1(strStart, IDS_ACTION_START, VERSION_NUMBER_STRING);
165            LogAction(strStart);
166        }
167
168        VERIFY(m_ilHeader.Create(IDB_HEADER, 10, 1, RGB(255, 255, 255)));
169
170        //image list setup
171        HIMAGELIST hSystemSmallImageList;
172        SHFILEINFO ssfi;
173
174        //get a handle to the system small icon list
175        hSystemSmallImageList =
176            reinterpret_cast<HIMAGELIST>(SHGetFileInfo((LPCTSTR)_T("C:\\"),
177                                      0, &ssfi, sizeof(SHFILEINFO),
178                                      SHGFI_SYSICONINDEX | SHGFI_SMALLICON));
179
180   
181        //m_smallImageList.Attach(hSystemSmallImageList);
182        m_smallImageList = CImageList::FromHandle(hSystemSmallImageList);
183    }
184    catch (CException *e)
185    {
186        ASSERT(FALSE);
187        REPORT_ERROR(e);
188        e->Delete();
189    }
190}
191
192CEraserDoc::~CEraserDoc()
193{
194    TRACE("CEraserDoc::~CEraserDoc\n");
195
196    try
197    {
198        m_smallImageList->Detach();
199        m_stIcon.RemoveIcon();
200
201        if (!SavePreferences() && m_bLog)
202            LogAction(IDS_ERROR_PREFERENCES_SAVE);
203
204        if (m_bLog && !m_bLogOnlyErrors)
205            LogAction(IDS_ACTION_QUIT);
206
207    //  delete m_smallImageList;
208    }
209    catch (...)
210    {
211        ASSERT(FALSE);
212    }
213}
214
215BOOL CEraserDoc::OnNewDocument()
216{
217    TRACE("CEraserDoc::OnNewDocument\n");
218
219    try
220    {
221        if (!CDocument::OnNewDocument())
222            return FALSE;
223
224        Import(m_strAppDataPath + szDefaultFile, FALSE);
225        return TRUE;
226    }
227    catch (CException *e)
228    {
229        ASSERT(FALSE);
230        REPORT_ERROR(e);
231        e->Delete();
232    }
233
234    return FALSE;
235}
236
237
238
239/////////////////////////////////////////////////////////////////////////////
240// CEraserDoc serialization
241
242void CEraserDoc::Serialize(CArchive& ar)
243{
244    TRACE("CEraserDoc::Serialize\n");
245
246    CItem           *piItem     = 0;
247    CScheduleItem   *psiItem    = 0;
248
249    if (ar.IsStoring())
250    {
251        int iSize;
252
253        // remove invalid items
254        CleanList(m_paTasks, sizeof(CItem));
255        CleanList(m_paScheduledTasks, sizeof(CScheduleItem));
256
257        ar << static_cast<DWORD>(m_paTasks.GetSize() + m_paScheduledTasks.GetSize());
258
259        iSize = m_paTasks.GetSize();
260
261        while (iSize--)
262        {
263            piItem = static_cast<CItem*>(m_paTasks[iSize]);
264
265            ar << static_cast<WORD>(ITEMVERSION);
266            ar << static_cast<WORD>(ITEM_ID);
267            piItem->Serialize(ar);
268        }
269
270        iSize = m_paScheduledTasks.GetSize();
271
272        while (iSize--)
273        {
274            psiItem = static_cast<CScheduleItem*>(m_paScheduledTasks[iSize]);
275
276            ar << static_cast<WORD>(ITEMVERSION);
277            ar << static_cast<WORD>(SCHEDULE_ID);
278            psiItem->Serialize(ar);
279        }
280    }
281    else
282    {
283        DWORD dwCount = 0;
284        WORD  wID     = 0;
285        WORD  wItemID = 0;
286
287        ar >> dwCount;
288
289        for (DWORD dwItem = 0; dwItem < dwCount; dwItem++)
290        {
291            ar >> wID;
292
293            piItem = 0;
294            psiItem = 0;
295
296            if (wID >= ITEMVERSION_30 && wID <= ITEMVERSION)
297            {
298                ar >> wItemID;
299
300                try
301                {
302                    if (wItemID == ITEM_ID)
303                    {
304                        piItem = new CItem();
305
306                        switch (wID)
307                        {
308                        case ITEMVERSION:
309                            piItem->Serialize(ar);
310                            break;
311                        case ITEMVERSION_41:
312                            psiItem->Serialize(ar);
313                            break;
314#ifdef SCHEDULER_IMPORT_COMPATIBLE
315                        case ITEMVERSION_40:
316                            piItem->Serialize40(ar);
317                            break;
318                        case ITEMVERSION_30:
319                            piItem->Serialize30(ar);
320                            break;
321#endif
322                        default:
323                            AfxThrowArchiveException(CArchiveException::badIndex);
324                        }
325
326                        AddTask(piItem);
327                    }
328                    else if (wItemID == SCHEDULE_ID)
329                    {
330                        psiItem = new CScheduleItem();
331
332                        switch (wID)
333                        {
334                        case ITEMVERSION:
335                            psiItem->Serialize(ar);
336                            break;
337                        case ITEMVERSION_41:
338                            psiItem->Serialize41(ar);
339                            break;
340#ifdef SCHEDULER_IMPORT_COMPATIBLE
341                        case ITEMVERSION_40:
342                            psiItem->Serialize40(ar);
343                            break;
344                        case ITEMVERSION_30:
345                            psiItem->Serialize30(ar);
346                            break;
347#endif
348                        default:
349                            AfxThrowArchiveException(CArchiveException::badIndex);
350                        }
351
352                        AddScheduledTask(psiItem);
353                    }
354                }
355                catch (...)
356                {
357                    if (piItem)
358                    {
359                        delete piItem;
360                        piItem = 0;
361                    }
362
363                    if (psiItem)
364                    {
365                        delete psiItem;
366                        psiItem = 0;
367                    }
368
369                    ASSERT(FALSE);
370                    throw;
371                }
372            }
373#ifdef SCHEDULER_IMPORT_COMPATIBLE
374            else if (wID == ITEMVERSION_21)
375            {
376                psiItem = new CScheduleItem();
377
378                try
379                {
380                    psiItem->Serialize21(ar);
381                    AddScheduledTask(psiItem);
382                }
383                catch (...)
384                {
385                    delete psiItem;
386                    psiItem = 0;
387
388                    ASSERT(FALSE);
389                    throw;
390                }
391            }
392#endif
393            else
394            {
395                // unsupported format
396                AfxThrowArchiveException(CArchiveException::badIndex);
397            }
398        }
399    }
400}
401
402/////////////////////////////////////////////////////////////////////////////
403// CEraserDoc diagnostics
404
405#ifdef _DEBUG
406void CEraserDoc::AssertValid() const
407{
408    CDocument::AssertValid();
409}
410
411void CEraserDoc::Dump(CDumpContext& dc) const
412{
413    CDocument::Dump(dc);
414}
415#endif //_DEBUG
416
417/////////////////////////////////////////////////////////////////////////////
418// CEraserDoc commands
419
420BOOL CEraserDoc::OnOpenDocument(LPCTSTR lpszPathName)
421{
422    TRACE("CEraserDoc::OnOpenDocument\n");
423
424    try
425    {
426        if (!CDocument::OnNewDocument())
427            return FALSE;
428
429        Import(lpszPathName);
430
431        return TRUE;
432    }
433    catch (CException *e)
434    {
435        ASSERT(FALSE);
436        REPORT_ERROR(e);
437        e->Delete();
438    }
439
440    return FALSE;
441}
442
443void CEraserDoc::DeleteContents()
444{
445    TRACE("CEraserDoc::DeleteContents\n");
446
447    FreeTasks();
448    CDocument::DeleteContents();
449}
450
451void CEraserDoc::FreeTasks()
452{
453    TRACE("CEraserDoc::FreeTasks\n");
454
455    try
456    {
457        CItem         *piItem  = 0;
458        CScheduleItem *psiItem = 0;
459        int           iSize    = 0;
460
461        // tasks of type CItem
462        iSize = m_paTasks.GetSize();
463
464        while (iSize--)
465        {
466            piItem = static_cast<CItem*>(m_paTasks[iSize]);
467            if (AfxIsValidAddress(piItem, sizeof(CItem)))
468                delete piItem;
469
470            piItem = 0;
471        }
472
473        m_paTasks.RemoveAll();
474
475        // scheduled tasks of type CScheduleItem
476        iSize = m_paScheduledTasks.GetSize();
477
478        while (iSize--)
479        {
480            psiItem = static_cast<CScheduleItem*>(m_paScheduledTasks[iSize]);
481
482            if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
483                delete psiItem;
484
485            psiItem = 0;
486        }
487
488        m_paScheduledTasks.RemoveAll();
489    }
490    catch (CException *e)
491    {
492        ASSERT(FALSE);
493        REPORT_ERROR(e);
494        e->Delete();
495    }
496}
497
498BOOL CEraserDoc::AddTask(CItem *piItem)
499{
500    TRACE("CEraserDoc::AddTask\n");
501
502    if (AfxIsValidAddress(piItem, sizeof(CItem)))
503    {
504        try
505        {
506            CString strNew;
507            piItem->GetData(strNew);
508
509            CItem   *piCurrent  = 0;
510            int     iSize       = m_paTasks.GetSize();
511
512            // duplicates are not accepted for on-demand eraser
513
514            while (iSize--)
515            {
516                piCurrent = static_cast<CItem*>(m_paTasks[iSize]);
517                if (AfxIsValidAddress(piCurrent, sizeof(CItem)))
518                {
519                    if (!strNew.CompareNoCase((LPCTSTR)(piCurrent->GetData())))
520                        return FALSE;
521                }
522            }
523
524            m_paTasks.Add(static_cast<void*>(piItem));
525            return TRUE;
526        }
527        catch (CException *e)
528        {
529            ASSERT(FALSE);
530            REPORT_ERROR(e);
531            e->Delete();
532        }
533    }
534
535    return FALSE;
536}
537
538BOOL CEraserDoc::AddScheduledTask(CScheduleItem *psiItem)
539{
540    TRACE("CEraserDoc::AddScheduledTask\n");
541
542    if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
543    {
544        try
545        {
546            m_paScheduledTasks.Add(static_cast<void*>(psiItem));
547            return TRUE;
548        }
549        catch (CException *e)
550        {
551            ASSERT(FALSE);
552            REPORT_ERROR(e);
553            e->Delete();
554        }
555    }
556
557    return FALSE;
558}
559
560
561void CEraserDoc::OnUpdateFileExport(CCmdUI* pCmdUI)
562{
563    pCmdUI->Enable(m_paTasks.GetSize() > 0 || m_paScheduledTasks.GetSize() > 0);
564}
565
566void CEraserDoc::OnFileExport()
567{
568    TRACE("CEraserDoc::OnFileExport\n");
569    CFileDialogEx fd(FALSE,
570                     szFileExtension,
571                     szFileWCard,
572                     OFN_EXPLORER | OFN_PATHMUSTEXIST |
573                     OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
574                     szFileFilter,
575                     AfxGetMainWnd());
576
577    fd.m_ofn.lpstrTitle = szExportTitle;
578
579    if (fd.DoModal() == IDOK)
580    {
581        CString strFile = fd.GetPathName();
582        Export((LPCTSTR)strFile);
583    }
584}
585
586void CEraserDoc::OnFileImport()
587{
588    TRACE("CEraserDoc::OnFileImport\n");
589// Was CfileDialogEx now with MFC7 we can change back to MFC Class
590    CFileDialog fd(TRUE,
591                     szFileExtension,
592                     szFileWCard,
593                     OFN_EXPLORER | OFN_PATHMUSTEXIST |
594                     OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
595                     szFileFilter,
596                     AfxGetMainWnd());
597
598    fd.m_ofn.lpstrTitle = szImportTitle;
599
600    if (fd.DoModal() == IDOK)
601    {
602        CString strFile = fd.GetPathName();
603        Import((LPCTSTR)strFile);
604
605        UpdateAllViews(NULL, SCHEDULER_SET_TIMERS);
606    }
607}
608
609void CEraserDoc::OnUpdateTrayEnable(CCmdUI* pCmdUI)
610{
611    pCmdUI->SetCheck(m_bSchedulerEnabled);
612}
613
614void CEraserDoc::OnTrayEnable()
615{
616    TRACE("CEraserDoc::OnTrayEnable\n");
617
618    m_bSchedulerEnabled = !m_bSchedulerEnabled;
619
620    if (m_bLog && !m_bLogOnlyErrors)
621    {
622        if (m_bSchedulerEnabled)
623            LogAction(IDS_ACTION_ENABLED);
624        else
625            LogAction(IDS_ACTION_DISABLED);
626    }
627
628    UpdateToolTip();
629}
630
631void CEraserDoc::OnUpdateTrayShowWindow(CCmdUI* pCmdUI)
632{
633    try
634    {
635        CFrameWnd *pwndMain = static_cast<CFrameWnd*>(AfxGetMainWnd());
636        pCmdUI->Enable(!pwndMain->IsWindowVisible());
637    }
638    catch (...)
639    {
640        ASSERT(FALSE);
641        pCmdUI->Enable(FALSE);
642    }
643}
644
645void CEraserDoc::OnTrayShowWindow()
646{
647    TRACE("CEraserDoc::OnTrayShowWindow\n");
648
649    try
650    {
651        CMainFrame *pwndMain = static_cast<CMainFrame*>(AfxGetMainWnd());
652
653        if (!pwndMain->IsWindowVisible())
654        {
655            pwndMain->ShowWindow(SW_SHOW);
656
657            if (pwndMain->m_pwndChild->m_iActiveViewID == VIEW_SCHEDULER)
658            {
659                // if there are processes running, update the window
660                if (m_wProcessCount > 0)
661                    pwndMain->m_pwndChild->m_pSchedulerView->EraserWipeBegin();
662            }
663        }
664    }
665    catch (...)
666    {
667        ASSERT(FALSE);
668    }
669}
670
671BOOL CEraserDoc::LogAction(CString str)
672{
673    TRACE("CEraserDoc::LogAction(CString)\n");
674
675    BOOL bResult = FALSE;
676    CString strDate, strPath;
677
678    CStdioFile sf;
679
680    strPath = m_strExePath + szLogFile;
681
682    if (sf.Open(strPath, CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate | CFile::typeText))
683    {
684        strDate = GetTimeTimeZoneBased().Format();
685        str = strDate + ": " + str + "\n";
686
687
688        try
689        {
690            DWORD dwMax = m_dwMaxLogSize * 1024;
691            ULONGLONG dwCurrent = sf.GetLength() + str.GetLength();
692
693            if (m_dwMaxLogSize > 0 && dwMax < dwCurrent)
694            {
695                // must remove lines in order to keep the log
696                // file under the maximum size
697
698                CString strTmp;
699                int dwLen = dwMax - str.GetLength();
700
701                sf.Seek(-1*dwLen, CFile::end);
702                sf.ReadString(strTmp);
703
704                LPTSTR lpszTmp = strTmp.GetBufferSetLength(dwLen);
705                ZeroMemory(lpszTmp, dwLen);
706
707                sf.Read((LPVOID)lpszTmp, dwLen);
708
709                strTmp.ReleaseBuffer();
710                strTmp += str;
711
712                sf.SetLength(0);
713                sf.SeekToBegin();
714                sf.Write(strTmp, strTmp.GetLength());
715            }
716            else
717            {
718                // write to the end of the file
719                sf.SeekToEnd();
720                sf.WriteString(str);
721            }
722
723            bResult = TRUE;
724        }
725        catch (CException* e)
726        {
727            e->ReportError();           
728        }
729        catch (...)
730        {
731            ASSERT(FALSE);
732        }
733
734        sf.Close();
735    }
736
737    return bResult;
738}
739
740BOOL CEraserDoc::LogException(CException *e)
741{
742    TRACE("CEraserDoc::LogException\n");
743
744    try
745    {
746        TCHAR szCause[255];
747        e->GetErrorMessage(szCause, 255);
748
749        return LogAction(szCause);
750    }
751    catch (...)
752    {
753        ASSERT(FALSE);
754    }
755
756    return FALSE;
757}
758
759BOOL CEraserDoc::LogAction(UINT nResourceID)
760{
761    TRACE("CEraserDoc::LogAction(UINT)\n");
762
763    CString str;
764    BOOL bResult = FALSE;
765
766    try
767    {
768        if (str.LoadString(nResourceID))
769            bResult = LogAction(str);
770    }
771    catch (CException *e)
772    {
773        ASSERT(FALSE);
774
775        if (m_bLog)
776            LogException(e);
777
778        e->Delete();
779    }
780    catch (...)
781    {
782        ASSERT(FALSE);
783    }
784
785    return bResult;
786}
787
788void CEraserDoc::CalcNextAssignment()
789{
790    TRACE("CEraserDoc::CalcNextAssignment\n");
791
792    try
793    {
794        int iSize = m_paScheduledTasks.GetSize();
795
796        if (iSize > 0)
797        {
798            iSize--;
799
800            CScheduleItem   *psiItem    = static_cast<CScheduleItem*>(m_paScheduledTasks[iSize]);
801            COleDateTime    odtEarliest = psiItem->GetNextTime();
802
803            while (iSize--)
804            {
805                psiItem = static_cast<CScheduleItem*>(m_paScheduledTasks[iSize]);
806                if (AfxIsValidAddress(psiItem, sizeof(CScheduleItem)))
807                {
808                    if (psiItem->GetNextTime() < odtEarliest)
809                        odtEarliest = psiItem->GetNextTime();
810                }
811            }
812
813            m_strNextAssignment = odtEarliest.Format();
814        }
815        else
816            m_strNextAssignment.Empty();
817    }
818    catch (CException *e)
819    {
820        ASSERT(FALSE);
821
822        if (m_bLog)
823            LogException(e);
824
825        e->Delete();
826    }
827}
828
829void CEraserDoc::UpdateToolTip()
830{
831    TRACE("CEraserDoc::UpdateToolTip\n");
832
833    CString     strFormat;
834    CString     str;
835
836    try
837    {
838        if (m_wProcessCount == 0)
839        {
840            if (m_bSchedulerEnabled)
841            {
842                if (m_strNextAssignment.IsEmpty())
843                {
844                    strFormat.LoadString(IDS_TOOLTIP_WAITING);
845                    m_stIcon.SetTooltipText(strFormat);
846                }
847                else
848                {
849                    str.LoadString(IDS_TOOLTIP_NEXT);
850                    str += m_strNextAssignment;
851
852                    m_stIcon.SetTooltipText(str);
853                }
854
855                m_stIcon.SetIcon(IDI_ICON_TRAY);
856            }
857            else
858            {
859                strFormat.LoadString(IDS_TOOLTIP_DISABLED);
860                m_stIcon.SetTooltipText(strFormat);
861
862                m_stIcon.SetIcon(IDI_ICON_TRAY_DISABLED);
863            }
864        }
865        else
866        {
867            m_stIcon.SetIcon(IDI_ICON_TRAY_RUNNING);
868
869            strFormat.LoadString(IDS_TOOLTIP_PROCESSING);
870            str.Format(strFormat, m_wProcessCount);
871
872            if (str.CompareNoCase(m_stIcon.GetTooltipText()) != 0)
873                m_stIcon.SetTooltipText((LPCTSTR)str);
874        }
875    }
876    catch (CException *e)
877    {
878        ASSERT(FALSE);
879
880        if (m_bLog)
881            LogException(e);
882
883        e->Delete();
884    }
885}
886
887#define RESULT(result, statement) \
888    ((result) = ((statement) ? (result) : FALSE))
889
890__declspec(dllimport) bool no_registry;
891
892BOOL CEraserDoc::SavePreferences()
893{
894    TRACE("CEraserDoc::SavePreferences\n");
895
896    BOOL            bResult     = TRUE;
897    CKey            kReg_reg;
898    CIniKey         kReg_ini;
899    CKey           &kReg = no_registry ? kReg_ini : kReg_reg;
900    CString         strPath;
901    OSVERSIONINFO   ov;
902
903    strPath.Format("%s\\%s", ERASER_REGISTRY_BASE, szSettingsKey);
904
905    ZeroMemory(&ov, sizeof(OSVERSIONINFO));
906    ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
907
908    GetVersionEx(&ov);
909
910    // Scheduler Preferences
911    if (kReg.Open(HKEY_CURRENT_USER, strPath))
912    {
913        RESULT(bResult, kReg.SetValue(m_bSchedulerEnabled, szSchedulerEnabled));
914        RESULT(bResult, kReg.SetValue(m_bLog, szLog));
915        RESULT(bResult, kReg.SetValue(m_bLogOnlyErrors, szLogOnlyErrors));
916        RESULT(bResult, kReg.SetValue(m_bStartup, szStartup));
917        RESULT(bResult, kReg.SetValue(m_bQueueTasks, szQueueTasks));
918        RESULT(bResult, kReg.SetValue(m_bNoVisualErrors, szNoVisualErrors));
919        RESULT(bResult, kReg.SetValue(m_dwMaxLogSize, szMaxLogSize));
920
921        kReg.Close();
922    }
923    else
924        bResult = FALSE;
925
926    // Scheduler Startup
927    if (!no_registry) {
928        if (m_bStartup)
929        {
930            if (kReg.Open(HKEY_CURRENT_USER, szStartupPath))
931            {
932                TCHAR szApplicationFileName[MAX_PATH + 1];
933
934                if (GetModuleFileName(AfxGetInstanceHandle(), szApplicationFileName, MAX_PATH))
935                {
936                    CString strStartupCmdLine(szApplicationFileName);
937                    strStartupCmdLine += " ";
938                    strStartupCmdLine += NOWINDOW_PARAMETER;
939
940                    RESULT(bResult, kReg.SetValue((LPCTSTR)strStartupCmdLine, szRunOnStartup));
941                }
942                else
943                    bResult = FALSE;
944
945                kReg.Close();
946            }
947            else
948                bResult = FALSE;
949        }
950        else if (kReg.Open(HKEY_CURRENT_USER, szStartupPath, FALSE))
951        {
952            kReg.DeleteValue(szRunOnStartup);
953            kReg.Close();
954        }
955    }
956
957    // General Preferences
958
959    //cancel report on recycle bin clearance if m_bShellextResults is unchecked
960    const LPCTSTR REC_BIN_PKEY = "CLSID\\";
961    const LPCTSTR REC_BIN_SKEY = "Shell\\Eraserxt\\command";
962    const CString strWthReport = "\\Eraserl.exe -recycled -results ";
963    const CString strWoReport =  "\\Eraserl.exe -recycled ";
964
965    CString strDef = _T(""), strCmd, strOld = _T("");
966    CString strRecBinGUID = REC_BIN_PKEY + findRecycledBinGUID();
967    strRecBinGUID = strRecBinGUID + "\\" + REC_BIN_SKEY;
968   
969    if (!no_registry && kReg.Open(HKEY_CLASSES_ROOT,strRecBinGUID,FALSE))
970    {
971        char buf[_MAX_PATH];
972        _getcwd(buf,_MAX_PATH); //working directory
973        strCmd = buf;
974        if (m_bShellextResults == TRUE) strCmd = strCmd + strWthReport;
975        else strCmd = strCmd + strWoReport;
976        kReg.GetValue(strOld,strDef,"");
977        if (strOld != strCmd ) kReg.SetValue(strCmd,strDef);
978        kReg.Close();
979    }
980   
981   
982    if (kReg.Open(HKEY_CURRENT_USER, ERASER_REGISTRY_BASE))
983    {
984        if (m_dwStartView != (DWORD) -1)
985            RESULT(bResult, kReg.SetValue(m_dwStartView, szStartView));
986
987        RESULT(bResult, kReg.SetValue((LPVOID)&m_rWindowRect, szWindowRect, sizeof(RECT)));
988        RESULT(bResult, kReg.SetValue(m_bResultsForFiles, ERASER_REGISTRY_RESULTS_FILES));
989        RESULT(bResult, kReg.SetValue(m_bResultsForUnusedSpace, ERASER_REGISTRY_RESULTS_UNUSEDSPACE));
990        RESULT(bResult, kReg.SetValue(m_bResultsOnlyWhenFailed, ERASER_REGISTRY_RESULTS_WHENFAILED));
991        RESULT(bResult, kReg.SetValue(m_bShellextResults, ERASEXT_REGISTRY_RESULTS));
992        RESULT(bResult, kReg.SetValue(m_bErasextEnabled, ERASEXT_REGISTRY_ENABLED));
993        RESULT(bResult, kReg.SetValue(m_bEnableSlowPoll, ERASER_RANDOM_SLOW_POLL));
994        RESULT(bResult, kReg.SetValue(m_bIconAnimation, szIconAnimation));
995        RESULT(bResult, kReg.SetValue(m_bSmallIconView, szSmallIconView));
996        RESULT(bResult, kReg.SetValue(m_dwOutbarWidth, szOutBarWidth));
997        RESULT(bResult, kReg.SetValue(m_bNoTrayIcon, szNoTrayIcon));
998        RESULT(bResult, kReg.SetValue(m_bHideOnMinimize, szHideOnMinimize));
999        RESULT(bResult, kReg.SetValue(m_bViewInfoBar, szViewInfoBar));
1000        RESULT(bResult, kReg.SetValue(m_bResolveLock, szResolveLock));
1001        RESULT(bResult, kReg.SetValue(m_bResolveAskUser, szResolveAskUser));
1002       
1003        kReg.Close();
1004
1005    }
1006    else
1007        bResult = FALSE;
1008
1009    // Page File Clearing only on NT (works only if Admin so no errors here)
1010    if (ov.dwPlatformId == VER_PLATFORM_WIN32_NT)
1011    {
1012        if (kReg_reg.Open(HKEY_LOCAL_MACHINE, szClearSwapPath))
1013        {
1014            // need to set the registry key even if m_bClearSwap == false,
1015            // otherwise Windows 2000 overrides the setting when applying
1016            // local security policy
1017
1018            kReg_reg.SetValue(m_bClearSwap, szClearSwapValue);
1019            kReg_reg.Close();
1020        }
1021    }
1022
1023    return bResult;
1024}
1025
1026BOOL CEraserDoc::ReadPreferences()
1027{
1028    TRACE("CEraserDoc::ReadPreferences\n");
1029
1030    BOOL            bResult     = TRUE;
1031    CKey            kReg_reg;
1032    CIniKey         kReg_ini;
1033    CKey           &kReg = no_registry ? kReg_ini : kReg_reg;
1034    CString         strPath;
1035    OSVERSIONINFO   ov;
1036
1037    strPath.Format("%s\\%s", ERASER_REGISTRY_BASE, szSettingsKey);
1038
1039    ZeroMemory(&ov, sizeof(OSVERSIONINFO));
1040    ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1041
1042    GetVersionEx(&ov);
1043
1044    // Scheduler Preferences
1045    if (kReg.Open(HKEY_CURRENT_USER, strPath))
1046    {
1047        kReg.GetValue(m_bSchedulerEnabled, szSchedulerEnabled, TRUE);
1048        kReg.GetValue(m_bLog, szLog, TRUE);
1049        kReg.GetValue(m_bLogOnlyErrors, szLogOnlyErrors, FALSE);
1050        kReg.GetValue(m_bStartup, szStartup, TRUE);
1051        kReg.GetValue(m_bQueueTasks, szQueueTasks, TRUE);
1052        kReg.GetValue(m_bNoVisualErrors, szNoVisualErrors, FALSE);
1053        kReg.GetValue(m_dwMaxLogSize, szMaxLogSize, 10);
1054
1055        kReg.Close();
1056    }
1057    else
1058        bResult = FALSE;
1059
1060    // General Preferences
1061    if (kReg.Open(HKEY_CURRENT_USER, ERASER_REGISTRY_BASE))
1062    {
1063        if (m_dwStartView == (DWORD) -1)
1064            kReg.GetValue(m_dwStartView, szStartView, VIEW_ERASER);
1065
1066        ZeroMemory(&m_rWindowRect, sizeof(RECT));
1067
1068        if (kReg.GetValueSize(szWindowRect) == sizeof(RECT))
1069            kReg.GetValue((LPVOID)&m_rWindowRect, szWindowRect);
1070
1071        kReg.GetValue(m_bResultsForFiles, ERASER_REGISTRY_RESULTS_FILES, TRUE);
1072        kReg.GetValue(m_bResultsForUnusedSpace, ERASER_REGISTRY_RESULTS_UNUSEDSPACE, TRUE);
1073        kReg.GetValue(m_bResultsOnlyWhenFailed, ERASER_REGISTRY_RESULTS_WHENFAILED, FALSE);
1074        kReg.GetValue(m_bShellextResults, ERASEXT_REGISTRY_RESULTS, TRUE);
1075        kReg.GetValue(m_bErasextEnabled, ERASEXT_REGISTRY_ENABLED, TRUE);
1076        kReg.GetValue(m_bEnableSlowPoll, ERASER_RANDOM_SLOW_POLL, FALSE);
1077        kReg.GetValue(m_bIconAnimation, szIconAnimation, FALSE);
1078        kReg.GetValue(m_bSmallIconView, szSmallIconView, FALSE);
1079        kReg.GetValue(m_dwOutbarWidth, szOutBarWidth, 0);
1080        kReg.GetValue(m_bNoTrayIcon, szNoTrayIcon, FALSE);
1081        kReg.GetValue(m_bHideOnMinimize, szHideOnMinimize, FALSE);
1082        kReg.GetValue(m_bViewInfoBar, szViewInfoBar, FALSE);
1083        kReg.GetValue(m_bResolveLock, szResolveLock, TRUE);
1084        kReg.GetValue(m_bResolveAskUser, szResolveAskUser, TRUE);
1085       
1086
1087        kReg.Close();
1088    }
1089    else
1090        bResult = FALSE;
1091
1092    // Page File Clearing only on NT
1093    m_bClearSwap = FALSE;
1094
1095    if (ov.dwPlatformId == VER_PLATFORM_WIN32_NT)
1096    {
1097        if (kReg_reg.Open(HKEY_LOCAL_MACHINE, szClearSwapPath))
1098        {
1099            kReg_reg.GetValue(m_bClearSwap, szClearSwapValue, FALSE);
1100            kReg_reg.Close();
1101        }
1102    }
1103
1104    return bResult;
1105}
1106
1107void CEraserDoc::OnEditPreferencesGeneral()
1108{
1109    TRACE("CEraserDoc::OnEditPreferencesGeneral\n");
1110
1111    ReadPreferences();
1112
1113    CPreferencesSheet propSheet;
1114
1115    // General
1116
1117   
1118
1119    propSheet.m_pgEraser.m_bResultsForFiles         = m_bResultsForFiles;
1120    propSheet.m_pgEraser.m_bResultsForUnusedSpace   = m_bResultsForUnusedSpace;
1121    propSheet.m_pgEraser.m_bResultsOnlyWhenFailed   = m_bResultsOnlyWhenFailed;
1122    propSheet.m_pgEraser.m_bShellextResults         = m_bShellextResults;
1123    propSheet.m_pgEraser.m_bErasextEnabled          = m_bErasextEnabled;
1124    propSheet.m_pgEraser.m_bEnableSlowPoll          = m_bEnableSlowPoll;
1125    propSheet.m_pgEraser.m_bClearSwap               = m_bClearSwap;
1126    propSheet.m_pgEraser.m_bResolveLock             = m_bResolveLock;
1127    propSheet.m_pgEraser.m_bResolveAskUser          = m_bResolveAskUser;               
1128
1129
1130    // Scheduler
1131
1132    propSheet.m_pgScheduler.m_bNoTrayIcon           = m_bNoTrayIcon;
1133    propSheet.m_pgScheduler.m_bHideOnMinimize       = m_bHideOnMinimize;
1134    propSheet.m_pgScheduler.m_bLog                  = m_bLog;
1135    propSheet.m_pgScheduler.m_bLogOnlyErrors        = m_bLogOnlyErrors;
1136    propSheet.m_pgScheduler.m_bStartup              = m_bStartup;
1137    propSheet.m_pgScheduler.m_bEnabled              = m_bSchedulerEnabled;
1138    propSheet.m_pgScheduler.m_bQueueTasks           = m_bQueueTasks;
1139    propSheet.m_pgScheduler.m_bNoVisualErrors       = m_bNoVisualErrors;
1140    propSheet.m_pgScheduler.m_dwMaxLogSize          = m_dwMaxLogSize;
1141
1142    if (propSheet.DoModal())
1143    {
1144        // General
1145
1146        m_bResultsForFiles          = propSheet.m_pgEraser.m_bResultsForFiles;
1147        m_bResultsForUnusedSpace    = propSheet.m_pgEraser.m_bResultsForUnusedSpace;
1148        m_bResultsOnlyWhenFailed    = propSheet.m_pgEraser.m_bResultsOnlyWhenFailed;
1149        m_bShellextResults          = propSheet.m_pgEraser.m_bShellextResults;
1150        m_bErasextEnabled           = propSheet.m_pgEraser.m_bErasextEnabled;
1151        m_bEnableSlowPoll           = propSheet.m_pgEraser.m_bEnableSlowPoll;
1152        m_bClearSwap                = propSheet.m_pgEraser.m_bClearSwap;
1153        m_bResolveLock              = propSheet.m_pgEraser.m_bResolveLock;
1154        m_bResolveAskUser           = propSheet.m_pgEraser.m_bResolveAskUser;
1155
1156        // Scheduler
1157
1158        m_bNoTrayIcon               = propSheet.m_pgScheduler.m_bNoTrayIcon;
1159        m_bHideOnMinimize           = propSheet.m_pgScheduler.m_bHideOnMinimize;
1160        m_bLog                      = propSheet.m_pgScheduler.m_bLog;
1161        m_bLogOnlyErrors            = propSheet.m_pgScheduler.m_bLogOnlyErrors;
1162        m_bStartup                  = propSheet.m_pgScheduler.m_bStartup;
1163        m_bSchedulerEnabled         = propSheet.m_pgScheduler.m_bEnabled;
1164        m_bQueueTasks               = propSheet.m_pgScheduler.m_bQueueTasks;
1165        m_bNoVisualErrors           = propSheet.m_pgScheduler.m_bNoVisualErrors;
1166        m_dwMaxLogSize              = propSheet.m_pgScheduler.m_dwMaxLogSize;
1167
1168        if (!m_bNoTrayIcon && !m_stIcon.Visible())
1169            m_stIcon.ShowIcon();
1170        else if (m_bNoTrayIcon)
1171        {
1172            if (!m_bHideOnMinimize && !AfxGetMainWnd()->IsWindowVisible())
1173                AfxGetMainWnd()->ShowWindow(SW_SHOWMINIMIZED);
1174            else if (m_bHideOnMinimize && AfxGetMainWnd()->IsIconic())
1175                AfxGetMainWnd()->ShowWindow(SW_HIDE);
1176
1177            m_stIcon.HideIcon();
1178        }
1179
1180        UpdateToolTip();
1181
1182        if (!SavePreferences())
1183        {
1184            AfxTimeOutMessageBox(IDS_ERROR_PREFERENCES_SAVE, MB_ICONERROR);
1185
1186            if (m_bLog)
1187                LogAction(IDS_ERROR_PREFERENCES_SAVE);
1188        }
1189    }
1190}
1191
1192void CEraserDoc::OnEditPreferencesEraser()
1193{
1194    TRACE("CEraserDoc::OnEditPreferencesEraser\n");
1195    eraserShowOptions(AfxGetMainWnd()->GetSafeHwnd(), ERASER_PAGE_FILES);
1196}
1197
1198void CEraserDoc::OnFileViewLog()
1199{
1200    TRACE("CEraserDoc::OnFileViewLog\n");
1201
1202    CFileStatus fs;
1203    CString strPath = m_strExePath + szLogFile;
1204
1205    if (CFile::GetStatus((LPCTSTR)strPath, fs))
1206    {
1207        if (reinterpret_cast<int>(ShellExecute(NULL, "open", (LPCTSTR)strPath,
1208                                               NULL, NULL, SW_SHOWNORMAL)) <= 32)
1209        {
1210            AfxMessageBox(IDS_ERROR_VIEWLOG, MB_ICONERROR, 0);
1211        }
1212    }
1213    else
1214    {
1215        AfxMessageBox(IDS_INFO_NOLOG, MB_ICONINFORMATION, 0);
1216    }
1217}
1218
1219BOOL CEraserDoc::Export(LPCTSTR szFile, BOOL bErrors)
1220{
1221    TRACE("CEraserDoc::Export\n");
1222
1223    // export the present items into a file
1224
1225    CFileException fe;
1226    CFile* pFile = NULL;
1227
1228    pFile = GetFile(szFile, CFile::modeCreate |
1229                    CFile::modeReadWrite | CFile::shareExclusive, &fe);
1230
1231    if (pFile == NULL)
1232    {
1233        if (bErrors)
1234            ReportSaveLoadException(szFile, &fe, TRUE, AFX_IDP_INVALID_FILENAME);
1235        return FALSE;
1236    }
1237
1238    CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);
1239
1240    saveArchive.m_pDocument  = this;
1241    saveArchive.m_bForceFlat = FALSE;
1242
1243    try
1244    {
1245        CWaitCursor wait;
1246        Serialize(saveArchive);
1247
1248        saveArchive.Close();
1249        ReleaseFile(pFile, FALSE);
1250    }
1251    catch (CFileException* e)
1252    {
1253        ASSERT(FALSE);
1254
1255        ReleaseFile(pFile, TRUE);
1256
1257        if (bErrors)
1258        {
1259            try
1260            {
1261                ReportSaveLoadException(szFile, e, TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
1262            }
1263            catch (...)
1264            {
1265            }
1266        }
1267
1268        if (m_bLog)
1269            LogException(e);
1270
1271        e->Delete();
1272        return FALSE;
1273    }
1274    catch (CException *e)
1275    {
1276        ASSERT(FALSE);
1277
1278        ReleaseFile(pFile, TRUE);
1279
1280        if (bErrors)
1281            REPORT_ERROR(e);
1282
1283        if (m_bLog)
1284            LogException(e);
1285
1286        e->Delete();
1287        return FALSE;
1288    }
1289
1290    return TRUE;
1291}
1292
1293BOOL CEraserDoc::Import(LPCTSTR szFile, BOOL bErrors)
1294{
1295    TRACE("CEraserDoc::Import\n");
1296
1297    // import items from a file without removing
1298    // present items
1299
1300    CFileException fe;
1301    CFile* pFile = NULL;
1302
1303    pFile = GetFile(szFile, CFile::modeRead | CFile::shareDenyWrite, &fe);
1304
1305    if (pFile == NULL)
1306    {
1307        if (bErrors)
1308            ReportSaveLoadException(szFile, &fe, TRUE, AFX_IDP_INVALID_FILENAME);
1309        return FALSE;
1310    }
1311
1312    CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);
1313
1314    loadArchive.m_pDocument  = this;
1315    loadArchive.m_bForceFlat = FALSE;
1316
1317    try
1318    {
1319        CWaitCursor wait;
1320        if (pFile->GetLength() != 0)
1321            Serialize(loadArchive);
1322
1323        loadArchive.Close();
1324        ReleaseFile(pFile, FALSE);
1325    }
1326    catch (CFileException* e)
1327    {
1328        ASSERT(FALSE);
1329
1330        ReleaseFile(pFile, TRUE);
1331
1332        if (bErrors)
1333        {
1334            try
1335            {
1336                ReportSaveLoadException(szFile, e, TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
1337            }
1338            catch (...)
1339            {
1340            }
1341        }
1342
1343        if (m_bLog)
1344            LogException(e);
1345
1346        e->Delete();
1347        return FALSE;
1348    }
1349    catch (CException *e)
1350    {
1351        ASSERT(FALSE);
1352
1353        ReleaseFile(pFile, TRUE);
1354
1355        if (bErrors)
1356            REPORT_ERROR(e);
1357
1358        if (m_bLog)
1359            LogException(e);
1360
1361        e->Delete();
1362        return FALSE;
1363    }
1364
1365    return TRUE;
1366}
1367
1368BOOL CEraserDoc::SaveTasksToDefault()
1369{
1370    return Export(m_strAppDataPath + szDefaultFile);
1371}
1372
1373void CEraserDoc::OnCloseDocument()
1374{
1375    TRACE("CEraserDoc::OnCloseDocument\n");
1376
1377    try
1378    {
1379        SaveTasksToDefault();
1380        CDocument::OnCloseDocument();
1381    }
1382    catch (CException *e)
1383    {
1384        ASSERT(FALSE);
1385        REPORT_ERROR(e);
1386        e->Delete();
1387    }
1388}
1389
1390
1391//DEL void CEraserDoc::OnHelpReward()
1392//DEL {
1393//DEL     AfxGetApp()->WinHelp(HID_BASE_COMMAND + ID_HELP_REWARD);
1394//DEL }
1395
1396void CEraserDoc::CleanList(CPtrArray& rList, int iItemSize)
1397{
1398    int iSize = rList.GetSize();
1399    while (iSize--)
1400    {
1401        if (!AfxIsValidAddress(rList[iSize], iItemSize))
1402            rList.RemoveAt(iSize);
1403    }
1404    rList.FreeExtra();
1405}
Note: See TracBrowser for help on using the repository browser.