source: trunk/EraserDll/FileLockResolver.cpp @ 66

Revision 66, 5.7 KB checked in by lowjoel, 7 years ago (diff)

-Bumped the version number
-Fix the infinite loop when doing an erase on reboot

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// FileLockResolver.cpp
2// $Id$
3//
4// Eraser. Secure data removal. For Windows.
5// Copyright © 1997-2001  Sami Tolvanen (sami@tolvanen.com).
6// Copyright © 2001-2006  Garrett Trant (support@heidi.ie).
7// Copyright © 2007 The Eraser Project.
8//
9// This program is free software; you can redistribute it and/or
10// modify it under the terms of the GNU General Public License
11// as published by the Free Software Foundation; either version 2
12// of the License, or (at your option) any later version.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22// 02111-1307, USA.
23
24#include "stdafx.h"
25#include "FileLockResolver.h"
26#include "..\Launcher\Launcher.h"
27#include <fstream>
28#include <string>
29#include <iterator>
30#include <atlbase.h>
31
32#define LOCKED_FILE_LIST_NAME _T("lock")
33#define RUNONCE  "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce"
34#define LAUNCHER "Eraserl.exe"
35
36CFileLockResolver::CFileLockResolver(BOOL askUser)
37: m_bAskUser(askUser), m_hHandle(ERASER_INVALID_CONTEXT),
38  m_iMethod(0), m_iPasses(0)
39{
40
41}
42
43CFileLockResolver::CFileLockResolver(ERASER_HANDLE h, BOOL askUser)
44: m_bAskUser(askUser), m_iMethod(0), m_iPasses(0)
45{
46    SetHandle(h);
47}
48
49CFileLockResolver::~CFileLockResolver(void)
50{
51    Close();
52}
53
54void CFileLockResolver::SetHandle(ERASER_HANDLE h)
55{
56    m_hHandle = h;
57    eraserSetErrorHandler(h, ErrorHandler, this);
58}
59
60CString CFileLockResolver::GetLockFilePath(bool path_only)
61{
62    // Retrieve the path to the current binary
63    char fullname[MAX_PATH];
64    GetModuleFileName(AfxGetInstanceHandle(), fullname, sizeof(fullname));
65
66    // Then separate the path into its constituent parts
67    char filename[MAX_PATH];
68    char extension[MAX_PATH];
69    char pathname[MAX_PATH];
70    char drive[10];
71    _splitpath(fullname, drive, pathname, filename, extension); 
72
73    // Then generate the path which we want
74    CString result;
75    if (path_only)
76        result.Format("%s%s", drive, pathname);
77    else
78        result.Format("%s%s%d.%s", drive, pathname, time(0), LOCKED_FILE_LIST_NAME);
79    return result;
80}
81
82struct FileData
83{
84    std::string name;
85    int method;
86    unsigned int passes;
87
88    FileData()
89    {
90    }
91
92    FileData(const std::string& fname, int m, unsigned int pass)
93        : name(fname), method(m), passes(pass)
94    {
95    }
96
97    void read(std::istream& is)
98    {
99        is >> std::noskipws;
100        std::getline(is, name);
101        is >> method >> passes;
102    }
103
104    void write(std::ostream& os) const
105    {
106        os << std::noskipws;
107        os << name << std::endl << method << passes;
108    }
109};
110
111std::ostream& operator<< (std::ostream& os, const FileData& data)
112{
113    data.write(os);
114    return os;
115}
116
117std::istream& operator>> (std::istream& is, FileData& data)
118{
119    data.read(is);
120    return is;
121}
122
123void CFileLockResolver::HandleError(LPCTSTR szFileName, DWORD dwErrorCode, int method, unsigned int passes)
124{
125    if (ERROR_LOCK_VIOLATION == dwErrorCode
126        || ERROR_DRIVE_LOCKED == dwErrorCode
127        || ERROR_LOCKED == dwErrorCode
128        || ERROR_SHARING_VIOLATION == dwErrorCode)
129    {
130        if (TRUE == m_bAskUser)
131        {
132            if (IDYES == AfxMessageBox(CString("The file ") +
133                szFileName + "\nis locked by another process. Do you want to Erase the file after " +
134                "you restart your computer?", MB_YESNO | MB_ICONQUESTION))
135            {
136                if (m_strLockFileList.IsEmpty())
137                    m_strLockFileList = GetLockFilePath();
138                std::ofstream os(m_strLockFileList, std::ios_base::out | std::ios_base::app);       
139                os << FileData(szFileName, method, passes);
140
141                ASSERT(m_iMethod == 0 || m_iMethod == method);
142                ASSERT(m_iPasses == 0 || m_iPasses == passes);
143                m_iMethod = method;
144                m_iPasses = passes;
145            }
146        }
147    }
148}
149
150void CFileLockResolver::Resolve(LPCTSTR szFileName, CStringArray& ar)
151{
152    std::ifstream is(szFileName);
153    if (is.fail())
154        throw std::runtime_error("Unable to resolve locked files. Can't open file list");
155
156    while (!is.eof()) 
157    {
158        FileData data;
159        is >> data;
160        if (!data.name.empty())
161            ar.Add(data.name.c_str());
162    }
163    is.close();
164    DeleteFile(szFileName);
165}
166
167DWORD CFileLockResolver::ErrorHandler(LPCTSTR szFileName, DWORD dwErrorCode, void* ctx, void* param)
168{
169    CFileLockResolver* self(static_cast<CFileLockResolver*>(param));
170    CEraserContext* ectx(static_cast<CEraserContext* >(ctx));
171    self->HandleError(szFileName, dwErrorCode, ectx->m_lpmMethod->m_nMethodID, ectx->m_lpmMethod->m_nPasses);
172    return 0UL;
173}
174
175void CFileLockResolver::Close()
176{
177    eraserSetErrorHandler(m_hHandle, NULL, NULL);
178    if (m_strLockFileList.IsEmpty())
179        return;
180
181    //Using the method and the passes, generate a command line that will do the same thing as it does now.
182    CString method;
183    switch (m_iMethod)
184    {
185    case GUTMANN_METHOD_ID:
186        method = "Gutmann";
187        break;
188    case DOD_METHOD_ID:
189        method = "DoD";
190        break;
191    case DOD_E_METHOD_ID:
192        method = "DoD_E";
193        break;
194    case RANDOM_METHOD_ID:
195        method.Format("Random %d", m_iPasses);
196        break;
197    case FL2KB_METHOD_ID:
198        method = "First_Last2k";
199        break;
200    case SCHNEIER_METHOD_ID:
201        method = "Schneier";
202        break;
203    }
204
205    CString cmdLine(CString("\"") + LAUNCHER + "\" " + szResolveLock + " \"" +
206        m_strLockFileList + "\" -method " + method);
207
208    extern bool no_registry;
209    if (!no_registry)
210    {
211        CRegKey key;
212        if (ERROR_SUCCESS == key.Open(HKEY_LOCAL_MACHINE, RUNONCE))
213        {
214            // Find an unused eraser launcher ID
215            int i = 0;
216            ULONG bufSiz = 0;
217            const char* KeyName = "EraserRestartErase (%i)";
218            char KeyNameBuf[64];
219            do
220                sprintf(KeyNameBuf, KeyName, ++i);
221            while (key.QueryStringValue(KeyNameBuf, NULL, &bufSiz) == ERROR_SUCCESS);
222
223            // Then save to registry
224            key.SetStringValue(KeyNameBuf, cmdLine);
225            m_strLockFileList = "";
226            m_iMethod = 0;
227            m_iPasses = 0;
228        }
229    }
230}
Note: See TracBrowser for help on using the repository browser.