source: trunk/EraserDlg.cpp @ 23

Revision 23, 13.2 KB checked in by lowjoel, 7 years ago (diff)

Move all third-party code to the Shared and EraserUI folders. EraserUI contains UI-specific controls and other miscellany, Shared contains code helper classes.
EXCEPTION: DropTargetWnd?, OleTreeCtrl? and ShellTree? are elft in the root, because they have been modified quite extensively.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// EraserDlg.cpp
2//
3// Eraser. Secure data removal. For Windows.
4// Copyright © 1997-2001  Sami Tolvanen (sami@tolvanen.com).
5//
6// This program is free software; you can redistribute it and/or
7// modify it under the terms of the GNU General Public License
8// as published by the Free Software Foundation; either version 2
9// of the License, or (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program; if not, write to the Free Software
18// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19// 02111-1307, USA.
20
21#include "stdafx.h"
22#include "Eraser.h"
23
24#include "Item.h"
25#include "EraserUI\FitFileNameToScrn.h"
26#include "EraserUI\DriveCombo.h"
27#include "shared\FileHelper.h"
28#include "EraserDlg.h"
29
30#ifdef _DEBUG
31#define new DEBUG_NEW
32#undef THIS_FILE
33static char THIS_FILE[] = __FILE__;
34#endif
35
36/////////////////////////////////////////////////////////////////////////////
37// CEraserDlg dialog
38
39
40CEraserDlg::CEraserDlg(CWnd* pParent /*=NULL*/) :
41CDialog(CEraserDlg::IDD, pParent),
42m_bResultsForFiles(TRUE),
43m_bResultsForUnusedSpace(TRUE),
44m_bResultsOnlyWhenFailed(FALSE),
45m_bShowResults(FALSE),
46m_ehContext(ERASER_INVALID_CONTEXT),
47m_pLockResolver(NULL)
48{
49    //{{AFX_DATA_INIT(CEraserDlg)
50    m_strData = _T("");
51    m_strErasing = _T("");
52    m_strMessage = _T("");
53    m_strPass = _T("");
54    m_strPercent = _T("0%");
55    m_strPercentTotal = _T("0%");
56    m_strTime = _T("");
57    //}}AFX_DATA_INIT
58}
59
60
61void CEraserDlg::DoDataExchange(CDataExchange* pDX)
62{
63    CDialog::DoDataExchange(pDX);
64    //{{AFX_DATA_MAP(CEraserDlg)
65    DDX_Control(pDX, IDC_PROGRESS, m_pcProgress);
66    DDX_Control(pDX, IDC_PROGRESS_TOTAL, m_pcProgressTotal);
67    DDX_Text(pDX, IDC_STATIC_DATA, m_strData);
68    DDX_Text(pDX, IDC_STATIC_ERASING, m_strErasing);
69    DDX_Text(pDX, IDC_STATIC_MESSAGE, m_strMessage);
70    DDX_Text(pDX, IDC_STATIC_PASS, m_strPass);
71    DDX_Text(pDX, IDC_STATIC_PERCENT, m_strPercent);
72    DDX_Text(pDX, IDC_STATIC_PERCENT_TOTAL, m_strPercentTotal);
73    DDX_Text(pDX, IDC_STATIC_TIME, m_strTime);
74    //}}AFX_DATA_MAP
75}
76
77
78BEGIN_MESSAGE_MAP(CEraserDlg, CDialog)
79    //{{AFX_MSG_MAP(CEraserDlg)
80    ON_WM_DESTROY()
81    //}}AFX_MSG_MAP
82    ON_MESSAGE(WM_ERASERNOTIFY, OnEraserNotify)
83END_MESSAGE_MAP()
84
85/////////////////////////////////////////////////////////////////////////////
86// CEraserDlg message handlers
87
88void CEraserDlg::OnCancel()
89{
90    m_strMessage = "Terminating...";
91    m_strPercent.Empty();
92    m_strPercentTotal.Empty();
93    m_strPass.Empty();
94    m_strTime.Empty();
95    m_strData.Empty();
96    m_pcProgress.SetPos(0);
97    m_pcProgressTotal.SetPos(0);
98    UpdateData(FALSE);
99
100    GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
101    eraserStop(m_ehContext);
102}
103
104BOOL CEraserDlg::OnInitDialog()
105{
106    CDialog::OnInitDialog();
107
108    m_pcProgress.SetRange(0, 100);
109    m_pcProgress.SetStep(1);
110    m_pcProgress.SetPos(0);
111
112    m_pcProgressTotal.SetRange(0, 100);
113    m_pcProgressTotal.SetStep(1);
114    m_pcProgressTotal.SetPos(0);
115
116    if (!Erase())
117        DestroyWindow();
118
119    return TRUE;  // return TRUE unless you set the focus to a control
120                  // EXCEPTION: OCX Property Pages should return FALSE
121}
122
123BOOL CEraserDlg::Initialize(CPtrArray *ppaTasks)
124{
125    try
126    {
127        if (AfxIsValidAddress(ppaTasks, sizeof(CPtrArray)))
128        {
129            m_saFiles.RemoveAll();
130            m_saFolders.RemoveAll();
131            m_saDrives.RemoveAll();
132           
133            CItem   *piItem = 0;
134            CString strData;
135
136            int iSize = ppaTasks->GetSize();
137
138            while (iSize--)
139            {
140                piItem = static_cast<CItem*>(ppaTasks->GetAt(iSize));
141                piItem->GetData(strData);
142
143                switch (piItem->GetType())
144                {
145                case File:
146                    if (piItem->UseWildcards())
147                    {
148                        findMatchingFiles(strData, m_saFiles,
149                                          piItem->WildcardsInSubfolders());
150//                      CString temp;
151//                      for(int i = 0; i < m_saFiles.GetCount(); i++) {
152//                          temp += m_saFiles[i];
153//                          temp += "\n";
154//                          AfxMessageBox(temp);
155//                      }
156//                      return false;
157                    }
158                    else
159                    {
160                        m_saFiles.Add(strData);
161                    }
162                    break;
163                case Folder:
164                    {
165                        CStringArray saFolders;
166                        parseDirectory((LPCTSTR)strData,
167                                       m_saFiles,
168                                       saFolders,
169                                       piItem->Subfolders());
170
171                        if (piItem->RemoveFolder())
172                        {
173                            if (piItem->OnlySubfolders())
174                            {
175                                // remove the last folder from the list
176                                // since the user does not want to remove
177                                // it
178
179                                if (saFolders.GetSize() > 0)
180                                    saFolders.SetSize(saFolders.GetSize() - 1);
181                            }
182
183                            m_saFolders.InsertAt(0, &saFolders);
184                        }
185                    }
186                    break;
187                case Drive:
188                    if (strData == DRIVE_ALL_LOCAL)
189                        GetLocalHardDrives(m_saDrives);
190                    else
191                        m_saDrives.Add(strData);
192                    break;
193                case Mask:
194                    findMaskedElements(strData, m_saFiles, m_saFolders);
195                    break;
196                default:
197                    NODEFAULT;
198                }
199            }
200
201            return TRUE;
202        }
203    }
204    catch (CException *e)
205    {
206        ASSERT(FALSE);
207        REPORT_ERROR(e);
208        e->Delete();
209    }
210
211    return FALSE;
212}
213
214BOOL CEraserDlg::Erase()
215{
216    BOOL bReturn = FALSE;
217
218    if (eraserError(eraserIsValidContext(m_ehContext)))
219    {
220        if (eraserError(eraserCreateContext(&m_ehContext)))
221            return FALSE;
222    }
223
224    if (m_pLockResolver)
225    {
226        m_pLockResolver->SetHandle(m_ehContext);       
227    }
228   
229    // set notification window & message
230    VERIFY(eraserOK(eraserSetWindow(m_ehContext, GetSafeHwnd())));
231    VERIFY(eraserOK(eraserSetWindowMessage(m_ehContext, WM_ERASERNOTIFY)));
232    eraserSetFinishAction(m_ehContext, m_dwFinishAction);
233
234
235    // clear possible previous items
236    VERIFY(eraserOK(eraserClearItems(m_ehContext)));
237
238    // even if we wouldn't have any files to erase, call eraserStart
239    // and the user will see an error message when the Erasing Report
240    // is shown
241
242    if (m_saDrives.GetSize() == 0 || m_saFiles.GetSize() > 0)
243    {
244        // we either have files to erase, or we have nothing
245        // to erase...
246
247        if (m_bResultsForFiles)
248            m_bShowResults = TRUE;
249
250        VERIFY(eraserOK(eraserSetDataType(m_ehContext, ERASER_DATA_FILES)));
251
252        int iSize = m_saFiles.GetSize();
253        for (int i = 0; i < iSize; i++)
254        {
255            VERIFY(eraserOK(eraserAddItem(m_ehContext,
256                (LPVOID)(LPCTSTR)m_saFiles[i], (E_UINT16)m_saFiles[i].GetLength())));
257        }
258        m_saFiles.RemoveAll();
259
260        bReturn = eraserOK(eraserStart(m_ehContext));
261    }
262    else if (m_saDrives.GetSize() > 0)
263    {
264        if (m_bResultsForUnusedSpace)
265            m_bShowResults = TRUE;
266
267        VERIFY(eraserOK(eraserSetDataType(m_ehContext, ERASER_DATA_DRIVES)));
268
269        int iSize = m_saDrives.GetSize();
270        for (int i = 0; i < iSize; i++)
271        {
272            VERIFY(eraserOK(eraserAddItem(m_ehContext,
273                (LPVOID)(LPCTSTR)m_saDrives[i], (E_UINT16)m_saDrives[i].GetLength())));
274        }
275        m_saDrives.RemoveAll();
276
277       
278        bReturn = eraserOK(eraserStart(m_ehContext));
279    }
280
281    return bReturn;
282}
283
284LRESULT CEraserDlg::OnEraserNotify(WPARAM wParam, LPARAM)
285{
286    switch (wParam)
287    {
288    case ERASER_WIPE_BEGIN:
289        EraserWipeBegin();
290        break;
291    case ERASER_WIPE_UPDATE:
292        EraserWipeUpdate();
293        break;
294    case ERASER_WIPE_DONE:
295        EraserWipeDone();
296        break;
297    }
298
299    return TRUE;
300}
301
302BOOL CEraserDlg::EraserWipeBegin()
303{
304    ERASER_DATA_TYPE edt;
305    VERIFY(eraserOK(eraserGetDataType(m_ehContext, &edt)));
306
307    if (edt == ERASER_DATA_FILES)
308        m_strErasing = "Files";
309    else
310        m_strErasing = "Unused disk space";
311
312    TCHAR    szValue[255];
313    E_UINT16 uSize = 255;
314    E_UINT8  uValue = 0;
315
316    // data
317    if (eraserOK(eraserProgGetCurrentDataString(m_ehContext, (LPVOID)szValue, &uSize)))
318        m_strData = szValue;
319    fitFileNameToScrn(GetDlgItem(IDC_STATIC_DATA), m_strData);
320
321    // message
322    if (eraserOK(eraserProgGetMessage(m_ehContext, (LPVOID)szValue, &uSize)))
323        m_strMessage = szValue;
324
325    // progress
326    if (eraserOK(eraserDispFlags(m_ehContext, &uValue)))
327    {
328        if (bitSet(uValue, eraserDispInit))
329        {
330            m_pcProgress.SetPos(0);
331            m_strPercent = "0%";
332        }
333
334        // pass
335        if (!bitSet(uValue, eraserDispPass))
336            m_strPass.Empty();
337
338        // time
339        if (!bitSet(uValue, eraserDispTime))
340            m_strTime.Empty();
341    }
342
343    UpdateData(FALSE);
344
345    return TRUE;
346}
347
348BOOL CEraserDlg::EraserWipeUpdate()
349{
350    TCHAR    szValue[255];
351    E_UINT16 uSize = 255;
352    E_UINT8  uValue = 0;
353    CString  strPercent, strPercentTotal, strTime, strPass, strMessage;
354
355    // percent
356    if (eraserOK(eraserProgGetPercent(m_ehContext, &uValue)))
357    {
358        strPercent.Format("%u%%", uValue);
359        m_pcProgress.SetPos(uValue);
360    }
361
362    // total percent
363    if (eraserOK(eraserProgGetTotalPercent(m_ehContext, &uValue)))
364    {
365        strPercentTotal.Format("%u%%", uValue);
366        m_pcProgressTotal.SetPos(uValue);
367    }
368
369    // pass
370    if (eraserOK(eraserDispFlags(m_ehContext, &uValue)))
371    {
372        if (bitSet(uValue, eraserDispPass))
373        {
374            E_UINT16 current = 0, passes = 0;
375            if (eraserOK(eraserProgGetCurrentPass(m_ehContext, &current)) &&
376                eraserOK(eraserProgGetPasses(m_ehContext, &passes)))
377            {
378                strPass.Format("%u of %u", current, passes);
379            }
380        }
381
382        // show time?
383        if (bitSet(uValue, eraserDispTime))
384        {
385            // time left
386            E_UINT32 uTimeLeft = 0;
387            if (eraserOK(eraserProgGetTimeLeft(m_ehContext, &uTimeLeft)))
388            {
389                if (uTimeLeft > 120)
390                {
391                    uTimeLeft = (uTimeLeft / 60) + 1;
392                    strTime.Format("%u minutes left", uTimeLeft);
393                }
394                else if (uTimeLeft > 0)
395                {
396                    if (uTimeLeft % 5)
397                        strTime = m_strTime;
398                    else
399                        strTime.Format("%u seconds left", uTimeLeft);
400                }
401            }
402        }
403    }
404
405    // message
406    if (eraserOK(eraserProgGetMessage(m_ehContext, (LPVOID)szValue, &uSize)))
407        strMessage = szValue;
408
409    // update only if necessary to minimize flickering
410    if (m_strPercent != strPercent || strPercentTotal != m_strPercentTotal ||
411        m_strPass != strPass || m_strTime != strTime || m_strMessage != strMessage)
412    {
413        m_strPercent = strPercent;
414        m_strPercentTotal = strPercentTotal;
415        m_strPass = strPass;
416        m_strTime = strTime;
417        m_strMessage = strMessage;
418
419        UpdateData(FALSE);
420    }
421
422    return TRUE;
423}
424
425BOOL CEraserDlg::EraserWipeDone()
426{
427    // clear display
428    m_strMessage.Empty();
429    m_strPercent.Empty();
430    m_strPercentTotal.Empty();
431    m_strPass.Empty();
432    m_strTime.Empty();
433    m_strData.Empty();
434    m_pcProgress.SetPos(0);
435    m_pcProgressTotal.SetPos(0);
436    UpdateData(FALSE);
437
438   
439    // remove folders
440    int iSize = m_saFolders.GetSize();
441    if (iSize > 0)
442    {
443        for (int i = 0; i < iSize; i++)
444        {
445            if (eraserOK(eraserRemoveFolder((LPVOID)(LPCTSTR)m_saFolders[i],
446                    (E_UINT16)m_saFolders[i].GetLength(), ERASER_REMOVE_FOLDERONLY)))
447            {
448                SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, (LPCTSTR)m_saFolders[i], NULL);
449            }
450        }
451
452        m_saFolders.RemoveAll();
453    }
454
455    E_UINT8 uTerminated = 0;
456    BOOL bTerminated = eraserOK(eraserTerminated(m_ehContext, &uTerminated)) && uTerminated;
457
458    // continue with unused disk space?
459    if (!bTerminated && m_saDrives.GetSize() > 0)
460        Erase();
461    else
462    {
463        E_UINT32 uFailed = 0;
464        E_UINT16 uErrors = 0;
465        eraserFailedCount(m_ehContext, &uFailed);
466        eraserErrorStringCount(m_ehContext, &uErrors);
467
468        if (m_bShowResults && (!m_bResultsOnlyWhenFailed || (uFailed > 0 || uErrors > 0)))
469            eraserShowReport(m_ehContext, GetSafeHwnd());
470
471        if (bTerminated)
472            CDialog::OnCancel();
473        else
474            CDialog::OnOK();
475    }
476
477    return TRUE;
478}
479
480void CEraserDlg::OnDestroy()
481{
482    if (m_pLockResolver)
483    {
484        m_pLockResolver->Close();
485        m_pLockResolver = NULL;
486    }
487    eraserDestroyContext(m_ehContext);
488    m_ehContext = ERASER_INVALID_CONTEXT;
489    CDialog::OnDestroy();
490}
Note: See TracBrowser for help on using the repository browser.