Reactos
at master 309 lines 7.8 kB view raw
1/* 2 * Copyright 2004 Martin Fuchs 3 * 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. 8 * 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. 13 * 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 17 */ 18 19 20 // 21 // Explorer clone 22 // 23 // ntobjfs.cpp 24 // 25 // Martin Fuchs, 31.01.2004 26 // 27 28 29#include <precomp.h> 30 31#include "regfs.h" 32 33 34void RegDirectory::read_directory(int scan_flags) 35{ 36 CONTEXT("RegDirectory::read_directory()"); 37 38 Entry* first_entry = NULL; 39 int level = _level + 1; 40 41 TCHAR buffer[MAX_PATH]; 42 43 _tcscpy(buffer, (LPCTSTR)_path); 44 LPTSTR pname = buffer + _tcslen(buffer); 45 int plen = MAX_PATH - _tcslen(buffer); 46 47 HKEY hkey; 48 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--; 52 53 TCHAR name[MAX_PATH], class_name[MAX_PATH]; 54 WIN32_FIND_DATA w32fd; 55 Entry* last = NULL; 56 RegEntry* entry; 57 58 for(int idx=0; ; ++idx) { 59 memset(&w32fd, 0, sizeof(WIN32_FIND_DATA)); 60 61 DWORD name_len = MAX_PATH; 62 DWORD class_len = MAX_PATH; 63 64 if (RegEnumKeyEx(hkey, idx, name, &name_len, 0, class_name, &class_len, &w32fd.ftLastWriteTime)) 65 break; 66 67 w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 68 _tcsncpy(w32fd.cFileName, name, name_len); 69 70 _tcscpy_s(pname, plen, name); 71 entry = new RegDirectory(this, buffer, _hKeyRoot); 72 73 memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); 74 75 if (class_len) 76 entry->_type_name = _tcsdup(String(class_name, class_len)); 77 78 if (!first_entry) 79 first_entry = entry; 80 81 if (last) 82 last->_next = entry; 83 84 entry->_level = level; 85 86 last = entry; 87 } 88/* 89 TCHAR value[MAX_PATH]; 90 LONG value_len = sizeof(value); 91 92 if (!RegQueryValue(hkey, NULL, value, &value_len) && value_len>1) { 93 memset(&w32fd, 0, sizeof(WIN32_FIND_DATA)); 94 95 lstrcpy(w32fd.cFileName, TEXT("(Default)")); 96 97 entry = new RegEntry(this); 98 99 memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); 100 101 entry->_content = _tcsdup(value); 102 103 if (!first_entry) 104 first_entry = entry; 105 106 if (last) 107 last->_next = entry; 108 109 entry->_level = level; 110 111 last = entry; 112 } 113*/ 114 DWORD type; 115 for(int idx=0; ; ++idx) { 116 DWORD name_len = MAX_PATH; 117 118 if (RegEnumValue(hkey, idx, name, &name_len, 0, &type, NULL, NULL)) 119 break; 120 121 memset(&w32fd, 0, sizeof(WIN32_FIND_DATA)); 122 123 if (name[0]) 124 lstrcpy(w32fd.cFileName, name); 125 else 126 lstrcpy(w32fd.cFileName, TEXT("(Default)")); 127 128 entry = new RegEntry(this); 129 130 memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA)); 131 132 switch(type) { 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; 145 } 146 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); 150 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) { 155 TCHAR b[32]; 156 _stprintf(b, TEXT("%ld"), *(DWORD*)&value); 157 entry->_content = _tcsdup(b); 158 } 159 } 160 161 if (!first_entry) 162 first_entry = entry; 163 164 if (last) 165 last->_next = entry; 166 167 entry->_level = level; 168 169 last = entry; 170 } 171 172 if (last) 173 last->_next = NULL; 174 175 RegCloseKey(hkey); 176 } 177 178 _down = first_entry; 179 _scanned = true; 180} 181 182 183const void* RegDirectory::get_next_path_component(const void* p) const 184{ 185 LPCTSTR s = (LPCTSTR) p; 186 187 while(*s && *s!=TEXT('\\')) 188 ++s; 189 190 while(*s==TEXT('\\')) 191 ++s; 192 193 if (!*s) 194 return NULL; 195 196 return s; 197} 198 199 200Entry* RegDirectory::find_entry(const void* p) 201{ 202 LPCTSTR name = (LPCTSTR)p; 203 204 for(Entry*entry=_down; entry; entry=entry->_next) { 205 LPCTSTR p = name; 206 LPCTSTR q = entry->_data.cFileName; 207 208 do { 209 if (!*p || *p==TEXT('\\') || *p==TEXT('/')) 210 return entry; 211 } while(tolower(*p++) == tolower(*q++)); 212 213 p = name; 214 q = entry->_data.cAlternateFileName; 215 216 do { 217 if (!*p || *p==TEXT('\\') || *p==TEXT('/')) 218 return entry; 219 } while(tolower(*p++) == tolower(*q++)); 220 } 221 222 return NULL; 223} 224 225 226 // get full path of specified registry entry 227bool RegEntry::get_path(PTSTR path, size_t path_count) const 228{ 229 return get_path_base ( path, path_count, ET_REGISTRY ); 230} 231 232BOOL RegEntry::launch_entry(HWND hwnd, UINT nCmdShow) 233{ 234 return FALSE; 235} 236 237 238RegDirectory::RegDirectory(Entry* parent, LPCTSTR path, HKEY hKeyRoot) 239 : RegEntry(parent), 240 _hKeyRoot(hKeyRoot) 241{ 242 _path = _tcsdup(path); 243 244 memset(&_data, 0, sizeof(WIN32_FIND_DATA)); 245 _data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 246} 247 248 249void RegistryRoot::read_directory(int scan_flags) 250{ 251 Entry *entry, *last, *first_entry; 252 int level = _level + 1; 253 254 _data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 255 256 entry = new RegDirectory(this, TEXT("\\"), HKEY_CURRENT_USER); 257 _tcscpy(entry->_data.cFileName, TEXT("HKEY_CURRENT_USER")); 258 entry->_level = level; 259 260 first_entry = entry; 261 last = entry; 262 263 entry = new RegDirectory(this, TEXT("\\"), HKEY_LOCAL_MACHINE); 264 _tcscpy(entry->_data.cFileName, TEXT("HKEY_LOCAL_MACHINE")); 265 entry->_level = level; 266 267 last->_next = entry; 268 last = entry; 269 270 entry = new RegDirectory(this, TEXT("\\"), HKEY_CLASSES_ROOT); 271 _tcscpy(entry->_data.cFileName, TEXT("HKEY_CLASSES_ROOT")); 272 entry->_level = level; 273 274 last->_next = entry; 275 last = entry; 276 277 entry = new RegDirectory(this, TEXT("\\"), HKEY_USERS); 278 _tcscpy(entry->_data.cFileName, TEXT("HKEY_USERS")); 279 entry->_level = level; 280 281 last->_next = entry; 282 last = entry; 283/* 284 entry = new RegDirectory(this, TEXT("\\"), HKEY_PERFORMANCE_DATA); 285 _tcscpy(entry->_data.cFileName, TEXT("HKEY_PERFORMANCE_DATA")); 286 entry->_level = level; 287 288 last->_next = entry; 289 last = entry; 290*/ 291 entry = new RegDirectory(this, TEXT("\\"), HKEY_CURRENT_CONFIG); 292 _tcscpy(entry->_data.cFileName, TEXT("HKEY_CURRENT_CONFIG")); 293 entry->_level = level; 294 295 last->_next = entry; 296 last = entry; 297/* 298 entry = new RegDirectory(this, TEXT("\\"), HKEY_DYN_DATA); 299 _tcscpy(entry->_data.cFileName, TEXT("HKEY_DYN_DATA")); 300 entry->_level = level; 301 302 last->_next = entry; 303 last = entry; 304*/ 305 last->_next = NULL; 306 307 _down = first_entry; 308 _scanned = true; 309}