source: trunk/shared/key.cpp @ 32

Revision 32, 12.7 KB checked in by lowjoel, 7 years ago (diff)

-Commit my fix for files which have filenames which are too long for the standard Windows filename handling to work
-Commit my fix to ignore files which are actually junctions or symbolic links
-UNC files are now ignored during free space wipes
-Silenced a few unused formal parameter warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1// key.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 "key.h"
23
24#ifdef _DEBUG
25#undef THIS_FILE
26static char BASED_CODE THIS_FILE[] = __FILE__;
27#endif
28
29/////////////////////////////////////////////////////////////////////////////
30// CKey
31
32CKey::CKey() :
33m_hKey(NULL)
34{
35
36}
37
38CKey::~CKey()
39{
40    Close();
41}
42
43void CKey::Close()
44{
45    if (m_hKey != NULL)
46    {
47        LONG lRes = RegCloseKey(m_hKey);
48        ASSERT(lRes == ERROR_SUCCESS);
49        m_hKey = NULL;
50    }
51}
52
53BOOL CKey::Open(HKEY hKey, LPCTSTR lpszKeyName, BOOL bCreate /*=TRUE*/)
54{
55    ASSERT(hKey != NULL);
56    DWORD dwDisp = 0;
57    LONG lReturn = 0;
58
59    if (bCreate)
60    {
61        lReturn = RegCreateKeyEx(hKey, lpszKeyName, 0,
62                                _T(""), REG_OPTION_NON_VOLATILE,
63                                KEY_ALL_ACCESS, NULL, &m_hKey, &dwDisp);
64    }
65    else
66    {
67        lReturn = RegOpenKeyEx(hKey, lpszKeyName, 0,KEY_ALL_ACCESS,
68                               &m_hKey);
69    }
70
71    SetLastError(static_cast<DWORD>(lReturn));
72
73    return (lReturn == ERROR_SUCCESS);
74}
75
76BOOL CKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName)
77{
78    ASSERT(m_hKey != NULL);
79    ASSERT(AfxIsValidString(lpszValue));
80    ASSERT(AfxIsValidString(lpszValueName));
81
82    LONG lReturn = RegSetValueEx(m_hKey, lpszValueName, 0, REG_SZ,
83                                reinterpret_cast<CONST BYTE*>(lpszValue),
84                                (lstrlen(lpszValue) + 1) * sizeof(TCHAR));
85
86    SetLastError(static_cast<DWORD>(lReturn));
87    return (lReturn == ERROR_SUCCESS);
88}
89
90BOOL CKey::SetValue(BOOL bValue, LPCTSTR lpszValueName)
91{
92    ASSERT(AfxIsValidString(lpszValueName));
93
94    return (SetValue(static_cast<DWORD>(bValue), lpszValueName));
95}
96
97BOOL CKey::SetValue(DWORD dwValue, LPCTSTR lpszValueName)
98{
99    ASSERT(AfxIsValidString(lpszValueName));
100    ASSERT(m_hKey != NULL);
101
102    LONG lReturn = RegSetValueEx(m_hKey, lpszValueName, 0, REG_DWORD,
103                                 reinterpret_cast<CONST BYTE*>(&dwValue),
104                                 sizeof(dwValue));
105
106    SetLastError(static_cast<DWORD>(lReturn));
107    return (lReturn == ERROR_SUCCESS);
108}
109
110BOOL CKey::SetValue(LPVOID pValue, LPCTSTR lpszValueName, DWORD dwSize)
111{
112    ASSERT(m_hKey != NULL);
113    ASSERT(AfxIsValidString(lpszValueName));
114
115    LONG lReturn = RegSetValueEx(m_hKey, lpszValueName, 0, REG_BINARY,
116                                 reinterpret_cast<CONST BYTE*>(pValue), dwSize);
117
118    SetLastError(static_cast<DWORD>(lReturn));
119    return (lReturn == ERROR_SUCCESS);
120}
121
122BOOL CKey::GetValue(CString& str, LPCTSTR lpszValueName, CString strDefault)
123{
124    ASSERT(m_hKey != NULL);
125    ASSERT(AfxIsValidString(str));
126    ASSERT(AfxIsValidString(lpszValueName));
127
128    str.Empty();
129
130    DWORD dw = 0;
131    DWORD dwType = 0;
132    LONG lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
133                                NULL, &dw);
134
135    if (lRes == ERROR_SUCCESS)
136    {
137        ASSERT(dwType == REG_SZ);
138
139        try
140        {
141            LPTSTR lpsz = str.GetBufferSetLength(dw);
142            lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
143                                   reinterpret_cast<BYTE*>(lpsz), &dw);
144
145            str.ReleaseBuffer();
146
147            SetLastError(static_cast<DWORD>(lRes));
148            return (lRes == ERROR_SUCCESS);
149        }
150        catch (CMemoryException *e)
151        {
152            ASSERT(FALSE);
153            e->ReportError(MB_ICONERROR);
154            e->Delete();
155        }
156        catch (...)
157        {
158            ASSERT(FALSE);
159        }
160    }
161    else
162    {
163        SetLastError(static_cast<DWORD>(lRes));
164    }
165
166    str = strDefault;
167    return FALSE;
168}
169
170BOOL CKey::GetValue(BOOL& bValue, LPCTSTR lpszValueName, BOOL bDefault)
171{
172    ASSERT(AfxIsValidString(lpszValueName));
173
174    BOOL bRes;
175    DWORD dwValue = static_cast<DWORD>(bValue);
176
177    bRes = GetValue(dwValue, lpszValueName, static_cast<DWORD>(bDefault));
178    bValue = static_cast<BOOL>(dwValue);
179
180    return bRes;
181}
182
183BOOL CKey::GetValue(DWORD& dwValue, LPCTSTR lpszValueName, DWORD dwDefault)
184{
185    ASSERT(m_hKey != NULL);
186    ASSERT(AfxIsValidString(lpszValueName));
187
188    DWORD dw = 0;
189    DWORD dwType = 0;
190    LONG lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
191                                NULL, &dw);
192
193    if (lRes == ERROR_SUCCESS &&
194        dwType == REG_DWORD)
195    {
196        lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
197                               reinterpret_cast<BYTE*>(&dwValue), &dw);
198
199        SetLastError(static_cast<DWORD>(lRes));
200        return (lRes == ERROR_SUCCESS);
201    }
202    else
203    {
204        dwValue = dwDefault;
205
206        SetLastError(static_cast<DWORD>(lRes));
207        return FALSE;
208    }
209}
210
211BOOL CKey::GetNextValueName(CString& strValName, DWORD index /*=0*/, LPDWORD valType /*=NULL*/)
212{
213     if (m_hKey == NULL) return FALSE;
214     DWORD dwNameLen = MAX_KEY_LENGTH;
215     char lpszValName[MAX_KEY_LENGTH];     
216     
217     try{
218          LONG lRes = RegEnumValue(m_hKey, index, (LPSTR)lpszValName, &dwNameLen, NULL, valType, NULL, NULL);
219         
220          if (lRes == ERROR_SUCCESS) {
221               strValName = lpszValName;
222               return TRUE;
223          }
224     }
225     catch (...) {
226          ASSERT(FALSE);
227     }
228    return FALSE;
229}
230
231
232BOOL CKey::GetValue(LPVOID pValue, LPCTSTR lpszValueName)
233{
234    ASSERT(m_hKey != NULL);
235    ASSERT(AfxIsValidString(lpszValueName));
236
237    DWORD dw = 0;
238    DWORD dwType = 0;
239    LONG lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
240                                NULL, &dw);
241
242    if (lRes == ERROR_SUCCESS &&
243        dwType == REG_BINARY)
244    {
245        lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
246                               static_cast<BYTE*>(pValue), &dw);
247
248        SetLastError(static_cast<DWORD>(lRes));
249        return (lRes == ERROR_SUCCESS);
250    }
251    else
252    {
253        SetLastError(static_cast<DWORD>(lRes));
254        return FALSE;
255    }
256}
257
258DWORD CKey::GetValueSize(LPCTSTR lpszValueName)
259{
260    ASSERT(m_hKey != NULL);
261    ASSERT(AfxIsValidString(lpszValueName));
262
263    DWORD dw = 0;
264    DWORD dwType = 0;
265
266    LONG lRes = RegQueryValueEx(m_hKey, const_cast<LPTSTR>(lpszValueName), NULL, &dwType,
267                                NULL, &dw);
268
269    SetLastError(static_cast<DWORD>(lRes));
270
271    if (lRes != ERROR_SUCCESS) dw = 0;
272
273    return dw;
274}
275
276
277BOOL CKey::DeleteValue(LPCTSTR lpszValueName)
278{
279    ASSERT(m_hKey != NULL);
280    ASSERT(AfxIsValidString(lpszValueName));
281
282    LONG lReturn = RegDeleteValue(m_hKey, lpszValueName);
283    SetLastError(static_cast<DWORD>(lReturn));
284
285    return (lReturn == ERROR_SUCCESS);
286}
287
288// delete recursively for NT4
289BOOL CKey::DeleteKey(HKEY hStartKey, LPCTSTR pKeyName)
290{
291    ASSERT(AfxIsValidString(pKeyName));
292
293    DWORD dwRtn, dwSubKeyLength;
294    TCHAR szSubKey[MAX_KEY_LENGTH]; // (256) this should be dynamic.
295    HKEY hKey;
296
297    // do not allow NULL or empty key name
298    if (pKeyName && lstrlen(pKeyName))
299    {
300        // are we allowed to delete and enumerate keys?
301        if((dwRtn = RegOpenKeyEx(hStartKey,pKeyName, 0,
302                                 KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey )) == ERROR_SUCCESS)
303        {
304            while (dwRtn == ERROR_SUCCESS )
305            {
306                dwSubKeyLength = MAX_KEY_LENGTH;
307
308                dwRtn=RegEnumKeyEx(hKey,
309                    0,       // always index zero
310                    szSubKey,
311                    &dwSubKeyLength,
312                    NULL,
313                    NULL,
314                    NULL,
315                    NULL);
316
317                if (dwRtn == ERROR_SUCCESS)
318                {
319                    DeleteKey(hKey, szSubKey);
320                    continue;
321                }
322                else if (dwRtn == ERROR_NO_MORE_ITEMS)
323                    break;
324            }
325
326            // finally, delete the main key
327            dwRtn = RegDeleteKey(hStartKey, pKeyName);
328
329            RegCloseKey(hKey);
330
331            // Do not save return code because error
332            // has already occurred
333        }
334    }
335    // empty key name
336    else
337        dwRtn = ERROR_BADKEY;
338
339
340    SetLastError(dwRtn);
341    return (dwRtn == ERROR_SUCCESS);
342}
343
344BOOL CKey::IsEmpty()
345{
346    if (m_hKey == NULL)
347        return FALSE;
348
349    TCHAR szSubKey[MAX_KEY_LENGTH]; // (256) this should be dynamic.
350    DWORD dwRtn, dwSubKeyLength = MAX_KEY_LENGTH;
351
352    dwRtn = RegEnumKeyEx(m_hKey, 0, szSubKey, &dwSubKeyLength, NULL, NULL, NULL, NULL);
353
354    SetLastError(dwRtn);
355    return (dwRtn == ERROR_NO_MORE_ITEMS);
356}
357HKEY CKey::GetHandle()
358{
359    return m_hKey; 
360}
361
362
363
364#include <assert.h>
365
366CIniKey::CIniKey() {
367}
368CIniKey::~CIniKey() {
369}
370
371BOOL CIniKey::Open(HKEY /*hKey*/, LPCTSTR lpszKeyName, BOOL /*bCreate*/) {
372    section = lpszKeyName;
373    section.Replace('/', '\\');
374    int i = section.ReverseFind('\\');
375    if(i != -1)
376        section = section.Mid(i + 1);
377    if(!section.GetLength())
378        section = "default";
379    return true;
380}
381void CIniKey::Close() {
382}
383HKEY CIniKey::GetHandle() {
384    assert(("CIniKey::GetHandle() not implemented!", false));
385    return NULL;
386}
387
388BOOL CIniKey::SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName) {
389    if(!lpszValueName || !lpszValueName[0])
390        lpszValueName = "__default";
391    AfxGetApp()->WriteProfileString(section, lpszValueName, lpszValue);
392    ::WritePrivateProfileString(NULL, NULL, NULL, AfxGetApp()->m_pszProfileName);
393    return true;
394}
395BOOL CIniKey::SetValue(DWORD lpszValue, LPCTSTR lpszValueName) {
396    if(!lpszValueName || !lpszValueName[0])
397        lpszValueName = "__default";
398    AfxGetApp()->WriteProfileInt(section, lpszValueName, lpszValue);
399    ::WritePrivateProfileString(NULL, NULL, NULL, AfxGetApp()->m_pszProfileName);
400    return true;
401}
402BOOL CIniKey::SetValue(BOOL lpszValue, LPCTSTR lpszValueName) {
403    if(!lpszValueName || !lpszValueName[0])
404        lpszValueName = "__default";
405    AfxGetApp()->WriteProfileString(section, lpszValueName, lpszValue ? "yes" : "no");
406    ::WritePrivateProfileString(NULL, NULL, NULL, AfxGetApp()->m_pszProfileName);
407    return true;
408}
409BOOL CIniKey::SetValue(LPVOID lpszValue, LPCTSTR lpszValueName, DWORD dwSize) {
410    if(!lpszValue)
411        return false;
412    if(!lpszValueName || !lpszValueName[0])
413        lpszValueName = "__default";
414    AfxGetApp()->WriteProfileBinary(section, lpszValueName, (LPBYTE)lpszValue, dwSize);
415    ::WritePrivateProfileString(NULL, NULL, NULL, AfxGetApp()->m_pszProfileName);
416    return true;
417}
418
419BOOL CIniKey::GetValue(CString &str, LPCTSTR lpszValueName, CString strDefault) {
420    if(!lpszValueName || !lpszValueName[0])
421        lpszValueName = "__default";
422    str = AfxGetApp()->GetProfileString(section, lpszValueName, strDefault);
423    return true;
424}
425BOOL CIniKey::GetValue(DWORD &value, LPCTSTR lpszValueName, DWORD dwDefault) {
426    if(!lpszValueName || !lpszValueName[0])
427        lpszValueName = "__default";
428    value = AfxGetApp()->GetProfileInt(section, lpszValueName, dwDefault);
429    return true;
430}
431BOOL CIniKey::GetValue(BOOL &value, LPCTSTR lpszValueName, BOOL bDefault) {
432    if(!lpszValueName || !lpszValueName[0])
433        lpszValueName = "__default";
434    CString str = AfxGetApp()->GetProfileString(section, lpszValueName, bDefault ? "yes" : "no");
435    value = !_stricmp(str, "yes");
436    return true;
437}
438BOOL CIniKey::GetValue(LPVOID data, LPCTSTR lpszValueName) {
439    if(!lpszValueName || !lpszValueName[0])
440        lpszValueName = "__default";
441    LPBYTE data2 = NULL;
442    UINT bytes = 0;
443    BOOL ret = AfxGetApp()->GetProfileBinary(section, lpszValueName, &data2, &bytes);
444    if(ret && data) {
445        memcpy(data, data2, bytes);
446        delete[] data2;
447    }
448    return ret;
449}
450
451BOOL CIniKey::DeleteValue(LPCTSTR /*lpszValueName*/) {
452    return false;
453}
454
455BOOL CIniKey::IsEmpty() {
456    assert(("CIniKey::IsEmpty() not implemented!", false));
457    return false;
458}
459
460DWORD CIniKey::GetValueSize(LPCTSTR lpszValueName) {
461    if(!lpszValueName || !lpszValueName[0])
462        lpszValueName = "__default";
463    LPBYTE data = NULL;
464    UINT bytes = 0;
465    BOOL ret = AfxGetApp()->GetProfileBinary(section, lpszValueName, &data, &bytes);
466    if(ret && data)
467        delete[] data;
468    return bytes;
469}
470
471BOOL CIniKey::GetNextValueName(CString& strValName, DWORD /*index*/, LPDWORD /*valType*/) {
472    assert(("CIniKey::GetNextValueName() not implemented!", false));
473    strValName = "";
474    return false;
475}
476
Note: See TracBrowser for help on using the repository browser.