source: trunk/eraser5/EraserDll/Options.cpp @ 1294

Revision 1294, 8.2 KB checked in by lowjoel, 5 years ago (diff)

Upgrade the Eraser custom erasure methods to the new Unicode versions so that custom methods are preserved. Fixes #225.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// Options.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 "EraserDll.h"
23#include "Common.h"
24#include "Options.h"
25#include "..\shared\key.h"
26
27#define LIBRARYSETTINGS_SIZE     (sizeof(LibrarySettings) - sizeof(LPMETHOD))
28#define CMETHOD_SIZE             (sizeof(METHOD) - sizeof(LPPASS))
29#define MAX_CMETHOD_SIZE         (CMETHOD_SIZE + PASSES_MAX * sizeof(PASS))
30#define MAX_LIBRARYSETTINGS_SIZE (LIBRARYSETTINGS_SIZE + (MAX_CUSTOM_METHODS * MAX_CMETHOD_SIZE))
31#define LIBRARYVERSION           1 //Unicode library version. 0 is the ASCII one
32
33void
34setLibraryDefaults(LibrarySettings *pls)
35{
36    try {
37        ZeroMemory(pls, sizeof(LibrarySettings));
38
39        pls->m_nFileMethodID     = DEFAULT_FILE_METHOD_ID;
40        pls->m_nUDSMethodID      = DEFAULT_UDS_METHOD_ID;
41        pls->m_uItems            = (E_UINT8)-1; // select all
42        pls->m_nFileRandom       = PASSES_RND;
43        pls->m_nUDSRandom        = PASSES_RND;
44        pls->m_nCMethods         = 0;
45        pls->m_lpCMethods        = 0;
46    } catch (...) {
47        ASSERT(0);
48    }
49}
50
51extern bool no_registry;
52
53bool
54loadLibrarySettings(LibrarySettings *pls)
55{
56    try {
57        CKey kReg_reg;
58        CIniKey kReg_ini;
59        CKey &kReg = no_registry ? kReg_ini : kReg_reg;
60        bool    bResult = FALSE;
61        DWORD   LibraryVersion = 0;
62        E_UINT32  uSize;
63        E_PUINT8  lpData;
64
65        setLibraryDefaults(pls);
66
67        if (!kReg.Open(HKEY_CURRENT_USER, ERASER_REGISTRY_BASE)) {
68            return false;
69        }
70
71        //Get the version of the library database
72        kReg.GetValue(LibraryVersion, ERASER_REGISTRY_LIBRARY_VERSION, 0);
73
74        uSize = kReg.GetValueSize(ERASER_REGISTRY_LIBRARY);
75
76        if (uSize >= LIBRARYSETTINGS_SIZE && uSize <= MAX_LIBRARYSETTINGS_SIZE) {
77            lpData = new E_UINT8[uSize];
78            ZeroMemory(lpData, uSize);
79
80            if (kReg.GetValue((LPVOID)lpData, ERASER_REGISTRY_LIBRARY)) {
81                // basic fields
82                MoveMemory((LPVOID)pls, (LPCVOID)lpData, LIBRARYSETTINGS_SIZE);
83
84                // custom methods
85                if (pls->m_nCMethods > 0 && pls->m_nCMethods <= MAX_CUSTOM_METHODS) {
86                    pls->m_lpCMethods = new METHOD[pls->m_nCMethods];
87
88                    E_UINT32 uPos = LIBRARYSETTINGS_SIZE;
89#ifdef _UNICODE
90                    bool upgradeCustomMethods = LibraryVersion == LIBRARYVERSION ||
91                        AfxMessageBox(_T("An old version of Eraser settings have been found.\n\n")
92                        _T("Would you like to upgrade the settings to match the new format? Clicking no will likely ")
93                        _T("result in corrupted custom erase methods."), MB_YESNO) == IDYES;
94#endif
95
96                    for (E_UINT8 i = 0; i < pls->m_nCMethods; i++) {
97                        // custom method fields
98                        MoveMemory((LPVOID)(&pls->m_lpCMethods[i]),
99                                   (LPCVOID)(&lpData[uPos]),
100                                   CMETHOD_SIZE);
101
102                        uPos += CMETHOD_SIZE;
103
104#ifdef _UNICODE
105                        // upgrade the name of the method if this is an old library
106                        if (LibraryVersion < LIBRARYVERSION && upgradeCustomMethods)
107                        {
108                            // Cast the raw data to the old method base class
109                            MethodBaseA* ansiMethod = reinterpret_cast<MethodBaseA*>(&pls->m_lpCMethods[i]);
110                            _MethodBase unicodeMethod;
111
112                            // Migrate the data element by element
113                            memset(&unicodeMethod, 0, sizeof(_MethodBase));
114                            unicodeMethod.m_nMethodID = ansiMethod->m_nMethodID;
115                            unicodeMethod.m_nPasses = ansiMethod->m_nPasses;
116                            unicodeMethod.m_pwfFunction = ansiMethod->m_pwfFunction;
117                            unicodeMethod.m_bShuffle = ansiMethod->m_bShuffle;
118
119                            // Convert the method name to Unicode
120                            size_t convCount = 0;
121                            mbstowcs_s(&convCount, unicodeMethod.m_szDescription, DESCRIPTION_SIZE,
122                                ansiMethod->m_szDescription, DESCRIPTION_SIZE - 1);
123
124                            // Copy the new structure
125                            memcpy(ansiMethod, &unicodeMethod, sizeof(_MethodBase));
126
127                            // Move the buffer pointer backwards so that the passes loaded will be correct
128                            uPos -= (sizeof(wchar_t) - sizeof(char)) * DESCRIPTION_SIZE;
129                        }
130#endif
131
132                        // actual pass information
133                        if (pls->m_lpCMethods[i].m_nPasses > 0 &&
134                            pls->m_lpCMethods[i].m_nPasses <= PASSES_MAX) {
135                            pls->m_lpCMethods[i].m_lpPasses = new PASS[pls->m_lpCMethods[i].m_nPasses];
136                            ZeroMemory(pls->m_lpCMethods[i].m_lpPasses,
137                                       pls->m_lpCMethods[i].m_nPasses * sizeof(PASS));
138
139                            MoveMemory((LPVOID)(pls->m_lpCMethods[i].m_lpPasses),
140                                       (LPCVOID)(&lpData[uPos]),
141                                       pls->m_lpCMethods[i].m_nPasses * sizeof(PASS));
142
143                            uPos += (pls->m_lpCMethods[i].m_nPasses * sizeof(PASS));
144                        }
145                    }
146
147#ifdef _UNICODE
148                    if (LibraryVersion < LIBRARYVERSION && upgradeCustomMethods)
149                        saveLibrarySettings(pls);
150#endif
151                }
152
153                bResult = true;
154            }
155
156            delete[] lpData;
157            lpData = 0;
158        }
159
160        return bResult;
161    } catch (CException *e) {
162        ASSERT(0);
163        e->ReportError(MB_ICONERROR);
164        e->Delete();
165
166        try {
167            CKey kReg_reg;
168            CIniKey kReg_ini;
169            CKey &kReg = no_registry ? kReg_ini : kReg_reg;
170            if (kReg.Open(HKEY_CURRENT_USER, ERASER_REGISTRY_BASE)) {
171                kReg.DeleteValue(ERASER_REGISTRY_LIBRARY);
172            }
173        } catch (...) {
174            ASSERT(0);
175        }
176    }
177
178    return false;
179}
180
181bool
182saveLibrarySettings(LibrarySettings *pls)
183{
184    try {
185        CKey kReg_reg;
186        CIniKey kReg_ini;
187        CKey &kReg = no_registry ? kReg_ini : kReg_reg;
188        bool    bResult = FALSE;
189        E_PUINT8  lpData;
190        E_UINT8   i;
191        E_UINT32  uSize;
192        E_UINT32  uPos;
193
194        if (!kReg.Open(HKEY_CURRENT_USER, ERASER_REGISTRY_BASE)) {
195            return FALSE;
196        }
197
198        // write the library version
199        kReg.SetValue(LIBRARYVERSION, ERASER_REGISTRY_LIBRARY_VERSION);
200
201        // calculate data size
202        uSize = LIBRARYSETTINGS_SIZE + (pls->m_nCMethods * CMETHOD_SIZE);
203
204        for (i = 0; i < pls->m_nCMethods; i++) {
205            uSize += pls->m_lpCMethods[i].m_nPasses * sizeof(PASS);
206        }
207
208        // allocate memory
209        lpData = new E_UINT8[uSize];
210        ZeroMemory(lpData, uSize);
211
212        // basic information
213        MoveMemory((LPVOID)lpData, (LPCVOID)pls, LIBRARYSETTINGS_SIZE);
214        uPos = LIBRARYSETTINGS_SIZE;
215
216        // custom methods
217        for (i = 0; i < pls->m_nCMethods; i++) {
218            MoveMemory((LPVOID)(&lpData[uPos]),
219                       (LPCVOID)(&pls->m_lpCMethods[i]),
220                       CMETHOD_SIZE);
221
222            uPos += CMETHOD_SIZE;
223
224            // actual pass information
225            if (pls->m_lpCMethods[i].m_nPasses > 0 &&
226                pls->m_lpCMethods[i].m_nPasses <= PASSES_MAX) {
227                MoveMemory((LPVOID)(&lpData[uPos]),
228                           (LPCVOID)(pls->m_lpCMethods[i].m_lpPasses),
229                           pls->m_lpCMethods[i].m_nPasses * sizeof(PASS));
230
231                uPos += (pls->m_lpCMethods[i].m_nPasses * sizeof(PASS));
232            }
233        }
234
235        bResult = (kReg.SetValue((LPVOID)lpData, ERASER_REGISTRY_LIBRARY, uSize) != 0);
236
237        delete[] lpData;
238        lpData = 0;
239
240        return bResult;
241    } catch (CException *e) {
242        ASSERT(0);
243        e->ReportError(MB_ICONERROR);
244        e->Delete();
245    }
246
247    return false;
248}
Note: See TracBrowser for help on using the repository browser.