source: trunk/EraserDoc.cpp @ 41

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

Fixed bug http://bbs.heidi.ie/viewtopic.php?t=2648

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