2 * Copyright 2004 Martin Fuchs
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 // Martin Fuchs, 31.01.2004
34 void RegDirectory::read_directory(int scan_flags
)
36 CONTEXT("RegDirectory::read_directory()");
38 Entry
* first_entry
= NULL
;
39 int level
= _level
+ 1;
41 TCHAR buffer
[MAX_PATH
];
43 _tcscpy(buffer
, (LPCTSTR
)_path
);
44 LPTSTR pname
= buffer
+ _tcslen(buffer
);
45 int plen
= MAX_PATH
- _tcslen(buffer
);
49 if (!RegOpenKeyEx(_hKeyRoot
, *buffer
=='\\'?buffer
+1:buffer
, 0, STANDARD_RIGHTS_READ
|KEY_QUERY_VALUE
|KEY_ENUMERATE_SUB_KEYS
, &hkey
)) {
50 if (pname
[-1] != '\\')
51 *pname
++ = '\\', plen
--;
53 TCHAR name
[MAX_PATH
], class_name
[MAX_PATH
];
54 WIN32_FIND_DATA w32fd
;
58 for(int idx
=0; ; ++idx
) {
59 memset(&w32fd
, 0, sizeof(WIN32_FIND_DATA
));
61 DWORD name_len
= MAX_PATH
;
62 DWORD class_len
= MAX_PATH
;
64 if (RegEnumKeyEx(hkey
, idx
, name
, &name_len
, 0, class_name
, &class_len
, &w32fd
.ftLastWriteTime
))
67 w32fd
.dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
68 _tcsncpy(w32fd
.cFileName
, name
, name_len
);
70 _tcscpy_s(pname
, plen
, name
);
71 entry
= new RegDirectory(this, buffer
, _hKeyRoot
);
73 memcpy(&entry
->_data
, &w32fd
, sizeof(WIN32_FIND_DATA
));
76 entry
->_type_name
= _tcsdup(String(class_name
, class_len
));
84 entry
->_level
= level
;
89 TCHAR value[MAX_PATH];
90 LONG value_len = sizeof(value);
92 if (!RegQueryValue(hkey, NULL, value, &value_len) && value_len>1) {
93 memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
95 lstrcpy(w32fd.cFileName, TEXT("(Default)"));
97 entry = new RegEntry(this);
99 memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
101 entry->_content = _tcsdup(value);
109 entry->_level = level;
115 for(int idx
=0; ; ++idx
) {
116 DWORD name_len
= MAX_PATH
;
118 if (RegEnumValue(hkey
, idx
, name
, &name_len
, 0, &type
, NULL
, NULL
))
121 memset(&w32fd
, 0, sizeof(WIN32_FIND_DATA
));
124 lstrcpy(w32fd
.cFileName
, name
);
126 lstrcpy(w32fd
.cFileName
, TEXT("(Default)"));
128 entry
= new RegEntry(this);
130 memcpy(&entry
->_data
, &w32fd
, sizeof(WIN32_FIND_DATA
));
133 case REG_NONE
: entry
->_type_name
= _tcsdup(TEXT("REG_NONE")); break;
134 case REG_SZ
: entry
->_type_name
= _tcsdup(TEXT("REG_SZ")); break;
135 case REG_EXPAND_SZ
: entry
->_type_name
= _tcsdup(TEXT("REG_EXPAND_SZ")); break;
136 case REG_BINARY
: entry
->_type_name
= _tcsdup(TEXT("REG_BINARY")); break;
137 case REG_DWORD
: entry
->_type_name
= _tcsdup(TEXT("REG_DWORD")); break;
138 case REG_DWORD_BIG_ENDIAN
: entry
->_type_name
= _tcsdup(TEXT("REG_DWORD_BIG_ENDIAN")); break;
139 case REG_LINK
: entry
->_type_name
= _tcsdup(TEXT("REG_LINK")); break;
140 case REG_MULTI_SZ
: entry
->_type_name
= _tcsdup(TEXT("REG_MULTI_SZ")); break;
141 case REG_RESOURCE_LIST
: entry
->_type_name
= _tcsdup(TEXT("REG_RESOURCE_LIST")); break;
142 case REG_FULL_RESOURCE_DESCRIPTOR
: entry
->_type_name
= _tcsdup(TEXT("REG_FULL_RESOURCE_DESCRIPTOR")); break;
143 case REG_RESOURCE_REQUIREMENTS_LIST
: entry
->_type_name
= _tcsdup(TEXT("REG_RESOURCE_REQUIREMENTS_LIST"));break;
144 case REG_QWORD
: entry
->_type_name
= _tcsdup(TEXT("REG_QWORD")); break;
147 ///@todo This can also be done in the RegEnumValue() call if we dynamically adjust the return buffer size.
148 TCHAR value
[MAX_PATH
];
149 DWORD value_len
= sizeof(value
);
151 if (!RegQueryValueEx(hkey
, name
, NULL
, NULL
, (LPBYTE
)value
, &value_len
)) {
152 if (type
==REG_SZ
|| type
==REG_EXPAND_SZ
|| type
==REG_LINK
)
153 entry
->_content
= _tcsdup(value
);
154 else if (type
== REG_DWORD
) {
156 _stprintf(b
, TEXT("%ld"), *(DWORD
*)&value
);
157 entry
->_content
= _tcsdup(b
);
167 entry
->_level
= level
;
183 const void* RegDirectory::get_next_path_component(const void* p
) const
185 LPCTSTR s
= (LPCTSTR
) p
;
187 while(*s
&& *s
!=TEXT('\\'))
190 while(*s
==TEXT('\\'))
200 Entry
* RegDirectory::find_entry(const void* p
)
202 LPCTSTR name
= (LPCTSTR
)p
;
204 for(Entry
*entry
=_down
; entry
; entry
=entry
->_next
) {
206 LPCTSTR q
= entry
->_data
.cFileName
;
209 if (!*p
|| *p
==TEXT('\\') || *p
==TEXT('/'))
211 } while(tolower(*p
++) == tolower(*q
++));
214 q
= entry
->_data
.cAlternateFileName
;
217 if (!*p
|| *p
==TEXT('\\') || *p
==TEXT('/'))
219 } while(tolower(*p
++) == tolower(*q
++));
226 // get full path of specified registry entry
227 bool RegEntry::get_path(PTSTR path
, size_t path_count
) const
229 return get_path_base ( path
, path_count
, ET_REGISTRY
);
232 BOOL
RegEntry::launch_entry(HWND hwnd
, UINT nCmdShow
)
238 RegDirectory::RegDirectory(Entry
* parent
, LPCTSTR path
, HKEY hKeyRoot
)
242 _path
= _tcsdup(path
);
244 memset(&_data
, 0, sizeof(WIN32_FIND_DATA
));
245 _data
.dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
249 void RegistryRoot::read_directory(int scan_flags
)
251 Entry
*entry
, *last
, *first_entry
;
252 int level
= _level
+ 1;
254 _data
.dwFileAttributes
|= FILE_ATTRIBUTE_DIRECTORY
;
256 entry
= new RegDirectory(this, TEXT("\\"), HKEY_CURRENT_USER
);
257 _tcscpy(entry
->_data
.cFileName
, TEXT("HKEY_CURRENT_USER"));
258 entry
->_level
= level
;
263 entry
= new RegDirectory(this, TEXT("\\"), HKEY_LOCAL_MACHINE
);
264 _tcscpy(entry
->_data
.cFileName
, TEXT("HKEY_LOCAL_MACHINE"));
265 entry
->_level
= level
;
270 entry
= new RegDirectory(this, TEXT("\\"), HKEY_CLASSES_ROOT
);
271 _tcscpy(entry
->_data
.cFileName
, TEXT("HKEY_CLASSES_ROOT"));
272 entry
->_level
= level
;
277 entry
= new RegDirectory(this, TEXT("\\"), HKEY_USERS
);
278 _tcscpy(entry
->_data
.cFileName
, TEXT("HKEY_USERS"));
279 entry
->_level
= level
;
284 entry = new RegDirectory(this, TEXT("\\"), HKEY_PERFORMANCE_DATA);
285 _tcscpy(entry->_data.cFileName, TEXT("HKEY_PERFORMANCE_DATA"));
286 entry->_level = level;
291 entry
= new RegDirectory(this, TEXT("\\"), HKEY_CURRENT_CONFIG
);
292 _tcscpy(entry
->_data
.cFileName
, TEXT("HKEY_CURRENT_CONFIG"));
293 entry
->_level
= level
;
298 entry = new RegDirectory(this, TEXT("\\"), HKEY_DYN_DATA);
299 _tcscpy(entry->_data.cFileName, TEXT("HKEY_DYN_DATA"));
300 entry->_level = level;