| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/win/registry.h" | 5 #include "base/win/registry.h" |
| 6 | 6 |
| 7 #include <shlwapi.h> | 7 #include <shlwapi.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/threading/thread_restrictions.h" | 11 #include "base/threading/thread_restrictions.h" |
| 12 | 12 |
| 13 #pragma comment(lib, "shlwapi.lib") // for SHDeleteKey | 13 #pragma comment(lib, "shlwapi.lib") // for SHDeleteKey |
| 14 | 14 |
| 15 namespace base { | 15 namespace base { |
| 16 namespace win { | 16 namespace win { |
| 17 | 17 |
| 18 // RegKey ---------------------------------------------------------------------- | 18 // RegKey ---------------------------------------------------------------------- |
| 19 | 19 |
| 20 RegKey::RegKey() | 20 RegKey::RegKey() |
| 21 : key_(NULL), | 21 : key_(NULL), |
| 22 watch_event_(0) { | 22 watch_event_(0) { |
| 23 } | 23 } |
| 24 | 24 |
| 25 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) | 25 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) |
| 26 : key_(NULL), | 26 : key_(NULL), |
| 27 watch_event_(0) { | 27 watch_event_(0) { |
| 28 base::ThreadRestrictions::AssertIOAllowed(); | |
| 29 if (rootkey) { | 28 if (rootkey) { |
| 30 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) | 29 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) |
| 31 Create(rootkey, subkey, access); | 30 Create(rootkey, subkey, access); |
| 32 else | 31 else |
| 33 Open(rootkey, subkey, access); | 32 Open(rootkey, subkey, access); |
| 34 } else { | 33 } else { |
| 35 DCHECK(!subkey); | 34 DCHECK(!subkey); |
| 36 } | 35 } |
| 37 } | 36 } |
| 38 | 37 |
| 39 RegKey::~RegKey() { | 38 RegKey::~RegKey() { |
| 40 Close(); | 39 Close(); |
| 41 } | 40 } |
| 42 | 41 |
| 43 LONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { | 42 LONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
| 44 DWORD disposition_value; | 43 DWORD disposition_value; |
| 45 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); | 44 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); |
| 46 } | 45 } |
| 47 | 46 |
| 48 LONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, | 47 LONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, |
| 49 DWORD* disposition, REGSAM access) { | 48 DWORD* disposition, REGSAM access) { |
| 50 base::ThreadRestrictions::AssertIOAllowed(); | |
| 51 DCHECK(rootkey && subkey && access && disposition); | 49 DCHECK(rootkey && subkey && access && disposition); |
| 52 Close(); | 50 Close(); |
| 53 | 51 |
| 54 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL, | 52 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL, |
| 55 REG_OPTION_NON_VOLATILE, access, NULL, &key_, | 53 REG_OPTION_NON_VOLATILE, access, NULL, &key_, |
| 56 disposition); | 54 disposition); |
| 57 return result; | 55 return result; |
| 58 } | 56 } |
| 59 | 57 |
| 60 LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) { | 58 LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) { |
| 61 base::ThreadRestrictions::AssertIOAllowed(); | |
| 62 DCHECK(name && access); | 59 DCHECK(name && access); |
| 63 | |
| 64 HKEY subkey = NULL; | 60 HKEY subkey = NULL; |
| 65 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, | 61 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, |
| 66 access, NULL, &subkey, NULL); | 62 access, NULL, &subkey, NULL); |
| 67 Close(); | 63 Close(); |
| 68 | 64 |
| 69 key_ = subkey; | 65 key_ = subkey; |
| 70 return result; | 66 return result; |
| 71 } | 67 } |
| 72 | 68 |
| 73 LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { | 69 LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
| 74 base::ThreadRestrictions::AssertIOAllowed(); | |
| 75 DCHECK(rootkey && subkey && access); | 70 DCHECK(rootkey && subkey && access); |
| 76 Close(); | 71 Close(); |
| 77 | 72 |
| 78 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); | 73 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); |
| 79 return result; | 74 return result; |
| 80 } | 75 } |
| 81 | 76 |
| 82 LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) { | 77 LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) { |
| 83 base::ThreadRestrictions::AssertIOAllowed(); | |
| 84 DCHECK(relative_key_name && access); | 78 DCHECK(relative_key_name && access); |
| 85 | |
| 86 HKEY subkey = NULL; | 79 HKEY subkey = NULL; |
| 87 LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey); | 80 LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey); |
| 88 | 81 |
| 89 // We have to close the current opened key before replacing it with the new | 82 // We have to close the current opened key before replacing it with the new |
| 90 // one. | 83 // one. |
| 91 Close(); | 84 Close(); |
| 92 | 85 |
| 93 key_ = subkey; | 86 key_ = subkey; |
| 94 return result; | 87 return result; |
| 95 } | 88 } |
| 96 | 89 |
| 97 void RegKey::Close() { | 90 void RegKey::Close() { |
| 98 base::ThreadRestrictions::AssertIOAllowed(); | |
| 99 StopWatching(); | 91 StopWatching(); |
| 100 if (key_) { | 92 if (key_) { |
| 101 ::RegCloseKey(key_); | 93 ::RegCloseKey(key_); |
| 102 key_ = NULL; | 94 key_ = NULL; |
| 103 } | 95 } |
| 104 } | 96 } |
| 105 | 97 |
| 106 bool RegKey::HasValue(const wchar_t* name) const { | 98 bool RegKey::HasValue(const wchar_t* name) const { |
| 107 base::ThreadRestrictions::AssertIOAllowed(); | |
| 108 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; | 99 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; |
| 109 } | 100 } |
| 110 | 101 |
| 111 DWORD RegKey::GetValueCount() const { | 102 DWORD RegKey::GetValueCount() const { |
| 112 base::ThreadRestrictions::AssertIOAllowed(); | |
| 113 DWORD count = 0; | 103 DWORD count = 0; |
| 114 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, | 104 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, |
| 115 NULL, NULL, NULL, NULL); | 105 NULL, NULL, NULL, NULL); |
| 116 return (result == ERROR_SUCCESS) ? count : 0; | 106 return (result == ERROR_SUCCESS) ? count : 0; |
| 117 } | 107 } |
| 118 | 108 |
| 119 LONG RegKey::GetValueNameAt(int index, std::wstring* name) const { | 109 LONG RegKey::GetValueNameAt(int index, std::wstring* name) const { |
| 120 base::ThreadRestrictions::AssertIOAllowed(); | |
| 121 wchar_t buf[256]; | 110 wchar_t buf[256]; |
| 122 DWORD bufsize = arraysize(buf); | 111 DWORD bufsize = arraysize(buf); |
| 123 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL); | 112 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL); |
| 124 if (r == ERROR_SUCCESS) | 113 if (r == ERROR_SUCCESS) |
| 125 *name = buf; | 114 *name = buf; |
| 126 | 115 |
| 127 return r; | 116 return r; |
| 128 } | 117 } |
| 129 | 118 |
| 130 LONG RegKey::DeleteKey(const wchar_t* name) { | 119 LONG RegKey::DeleteKey(const wchar_t* name) { |
| 131 base::ThreadRestrictions::AssertIOAllowed(); | |
| 132 DCHECK(key_); | 120 DCHECK(key_); |
| 133 DCHECK(name); | 121 DCHECK(name); |
| 134 LONG result = SHDeleteKey(key_, name); | 122 LONG result = SHDeleteKey(key_, name); |
| 135 return result; | 123 return result; |
| 136 } | 124 } |
| 137 | 125 |
| 138 LONG RegKey::DeleteValue(const wchar_t* value_name) { | 126 LONG RegKey::DeleteValue(const wchar_t* value_name) { |
| 139 base::ThreadRestrictions::AssertIOAllowed(); | |
| 140 DCHECK(key_); | 127 DCHECK(key_); |
| 141 DCHECK(value_name); | 128 DCHECK(value_name); |
| 142 LONG result = RegDeleteValue(key_, value_name); | 129 LONG result = RegDeleteValue(key_, value_name); |
| 143 return result; | 130 return result; |
| 144 } | 131 } |
| 145 | 132 |
| 146 LONG RegKey::ReadValueDW(const wchar_t* name, DWORD* out_value) const { | 133 LONG RegKey::ReadValueDW(const wchar_t* name, DWORD* out_value) const { |
| 147 DCHECK(out_value); | 134 DCHECK(out_value); |
| 148 DWORD type = REG_DWORD; | 135 DWORD type = REG_DWORD; |
| 149 DWORD size = sizeof(DWORD); | 136 DWORD size = sizeof(DWORD); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 170 size == sizeof(local_value)) | 157 size == sizeof(local_value)) |
| 171 *out_value = local_value; | 158 *out_value = local_value; |
| 172 else | 159 else |
| 173 result = ERROR_CANTREAD; | 160 result = ERROR_CANTREAD; |
| 174 } | 161 } |
| 175 | 162 |
| 176 return result; | 163 return result; |
| 177 } | 164 } |
| 178 | 165 |
| 179 LONG RegKey::ReadValue(const wchar_t* name, std::wstring* out_value) const { | 166 LONG RegKey::ReadValue(const wchar_t* name, std::wstring* out_value) const { |
| 180 base::ThreadRestrictions::AssertIOAllowed(); | |
| 181 DCHECK(out_value); | 167 DCHECK(out_value); |
| 182 const size_t kMaxStringLength = 1024; // This is after expansion. | 168 const size_t kMaxStringLength = 1024; // This is after expansion. |
| 183 // Use the one of the other forms of ReadValue if 1024 is too small for you. | 169 // Use the one of the other forms of ReadValue if 1024 is too small for you. |
| 184 wchar_t raw_value[kMaxStringLength]; | 170 wchar_t raw_value[kMaxStringLength]; |
| 185 DWORD type = REG_SZ, size = sizeof(raw_value); | 171 DWORD type = REG_SZ, size = sizeof(raw_value); |
| 186 LONG result = ReadValue(name, raw_value, &size, &type); | 172 LONG result = ReadValue(name, raw_value, &size, &type); |
| 187 if (result == ERROR_SUCCESS) { | 173 if (result == ERROR_SUCCESS) { |
| 188 if (type == REG_SZ) { | 174 if (type == REG_SZ) { |
| 189 *out_value = raw_value; | 175 *out_value = raw_value; |
| 190 } else if (type == REG_EXPAND_SZ) { | 176 } else if (type == REG_EXPAND_SZ) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 204 } | 190 } |
| 205 } | 191 } |
| 206 | 192 |
| 207 return result; | 193 return result; |
| 208 } | 194 } |
| 209 | 195 |
| 210 LONG RegKey::ReadValue(const wchar_t* name, | 196 LONG RegKey::ReadValue(const wchar_t* name, |
| 211 void* data, | 197 void* data, |
| 212 DWORD* dsize, | 198 DWORD* dsize, |
| 213 DWORD* dtype) const { | 199 DWORD* dtype) const { |
| 214 base::ThreadRestrictions::AssertIOAllowed(); | |
| 215 LONG result = RegQueryValueEx(key_, name, 0, dtype, | 200 LONG result = RegQueryValueEx(key_, name, 0, dtype, |
| 216 reinterpret_cast<LPBYTE>(data), dsize); | 201 reinterpret_cast<LPBYTE>(data), dsize); |
| 217 return result; | 202 return result; |
| 218 } | 203 } |
| 219 | 204 |
| 220 LONG RegKey::ReadValues(const wchar_t* name, | 205 LONG RegKey::ReadValues(const wchar_t* name, |
| 221 std::vector<std::wstring>* values) { | 206 std::vector<std::wstring>* values) { |
| 222 base::ThreadRestrictions::AssertIOAllowed(); | |
| 223 values->clear(); | 207 values->clear(); |
| 224 | 208 |
| 225 DWORD type = REG_MULTI_SZ; | 209 DWORD type = REG_MULTI_SZ; |
| 226 DWORD size = 0; | 210 DWORD size = 0; |
| 227 LONG result = ReadValue(name, NULL, &size, &type); | 211 LONG result = ReadValue(name, NULL, &size, &type); |
| 228 if (FAILED(result) || size == 0) | 212 if (FAILED(result) || size == 0) |
| 229 return result; | 213 return result; |
| 230 | 214 |
| 231 if (type != REG_MULTI_SZ) | 215 if (type != REG_MULTI_SZ) |
| 232 return ERROR_CANTREAD; | 216 return ERROR_CANTREAD; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 256 | 240 |
| 257 LONG RegKey::WriteValue(const wchar_t * name, const wchar_t* in_value) { | 241 LONG RegKey::WriteValue(const wchar_t * name, const wchar_t* in_value) { |
| 258 return WriteValue(name, in_value, | 242 return WriteValue(name, in_value, |
| 259 static_cast<DWORD>(sizeof(*in_value) * (wcslen(in_value) + 1)), REG_SZ); | 243 static_cast<DWORD>(sizeof(*in_value) * (wcslen(in_value) + 1)), REG_SZ); |
| 260 } | 244 } |
| 261 | 245 |
| 262 LONG RegKey::WriteValue(const wchar_t* name, | 246 LONG RegKey::WriteValue(const wchar_t* name, |
| 263 const void* data, | 247 const void* data, |
| 264 DWORD dsize, | 248 DWORD dsize, |
| 265 DWORD dtype) { | 249 DWORD dtype) { |
| 266 base::ThreadRestrictions::AssertIOAllowed(); | |
| 267 DCHECK(data || !dsize); | 250 DCHECK(data || !dsize); |
| 268 | 251 |
| 269 LONG result = RegSetValueEx(key_, name, 0, dtype, | 252 LONG result = RegSetValueEx(key_, name, 0, dtype, |
| 270 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); | 253 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); |
| 271 return result; | 254 return result; |
| 272 } | 255 } |
| 273 | 256 |
| 274 LONG RegKey::StartWatching() { | 257 LONG RegKey::StartWatching() { |
| 275 DCHECK(key_); | 258 DCHECK(key_); |
| 276 if (!watch_event_) | 259 if (!watch_event_) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 watch_event_ = 0; | 291 watch_event_ = 0; |
| 309 result = ERROR_SUCCESS; | 292 result = ERROR_SUCCESS; |
| 310 } | 293 } |
| 311 return result; | 294 return result; |
| 312 } | 295 } |
| 313 | 296 |
| 314 // RegistryValueIterator ------------------------------------------------------ | 297 // RegistryValueIterator ------------------------------------------------------ |
| 315 | 298 |
| 316 RegistryValueIterator::RegistryValueIterator(HKEY root_key, | 299 RegistryValueIterator::RegistryValueIterator(HKEY root_key, |
| 317 const wchar_t* folder_key) { | 300 const wchar_t* folder_key) { |
| 318 base::ThreadRestrictions::AssertIOAllowed(); | |
| 319 | |
| 320 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 301 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
| 321 if (result != ERROR_SUCCESS) { | 302 if (result != ERROR_SUCCESS) { |
| 322 key_ = NULL; | 303 key_ = NULL; |
| 323 } else { | 304 } else { |
| 324 DWORD count = 0; | 305 DWORD count = 0; |
| 325 result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, | 306 result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, |
| 326 NULL, NULL, NULL, NULL); | 307 NULL, NULL, NULL, NULL); |
| 327 | 308 |
| 328 if (result != ERROR_SUCCESS) { | 309 if (result != ERROR_SUCCESS) { |
| 329 ::RegCloseKey(key_); | 310 ::RegCloseKey(key_); |
| 330 key_ = NULL; | 311 key_ = NULL; |
| 331 } else { | 312 } else { |
| 332 index_ = count - 1; | 313 index_ = count - 1; |
| 333 } | 314 } |
| 334 } | 315 } |
| 335 | 316 |
| 336 Read(); | 317 Read(); |
| 337 } | 318 } |
| 338 | 319 |
| 339 RegistryValueIterator::~RegistryValueIterator() { | 320 RegistryValueIterator::~RegistryValueIterator() { |
| 340 base::ThreadRestrictions::AssertIOAllowed(); | |
| 341 if (key_) | 321 if (key_) |
| 342 ::RegCloseKey(key_); | 322 ::RegCloseKey(key_); |
| 343 } | 323 } |
| 344 | 324 |
| 345 DWORD RegistryValueIterator::ValueCount() const { | 325 DWORD RegistryValueIterator::ValueCount() const { |
| 346 base::ThreadRestrictions::AssertIOAllowed(); | |
| 347 DWORD count = 0; | 326 DWORD count = 0; |
| 348 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, | 327 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, |
| 349 &count, NULL, NULL, NULL, NULL); | 328 &count, NULL, NULL, NULL, NULL); |
| 350 if (result != ERROR_SUCCESS) | 329 if (result != ERROR_SUCCESS) |
| 351 return 0; | 330 return 0; |
| 352 | 331 |
| 353 return count; | 332 return count; |
| 354 } | 333 } |
| 355 | 334 |
| 356 bool RegistryValueIterator::Valid() const { | 335 bool RegistryValueIterator::Valid() const { |
| 357 return key_ != NULL && index_ >= 0; | 336 return key_ != NULL && index_ >= 0; |
| 358 } | 337 } |
| 359 | 338 |
| 360 void RegistryValueIterator::operator++() { | 339 void RegistryValueIterator::operator++() { |
| 361 --index_; | 340 --index_; |
| 362 Read(); | 341 Read(); |
| 363 } | 342 } |
| 364 | 343 |
| 365 bool RegistryValueIterator::Read() { | 344 bool RegistryValueIterator::Read() { |
| 366 base::ThreadRestrictions::AssertIOAllowed(); | |
| 367 if (Valid()) { | 345 if (Valid()) { |
| 368 DWORD ncount = arraysize(name_); | 346 DWORD ncount = arraysize(name_); |
| 369 value_size_ = sizeof(value_); | 347 value_size_ = sizeof(value_); |
| 370 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, | 348 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, |
| 371 reinterpret_cast<BYTE*>(value_), &value_size_); | 349 reinterpret_cast<BYTE*>(value_), &value_size_); |
| 372 if (ERROR_SUCCESS == r) | 350 if (ERROR_SUCCESS == r) |
| 373 return true; | 351 return true; |
| 374 } | 352 } |
| 375 | 353 |
| 376 name_[0] = '\0'; | 354 name_[0] = '\0'; |
| 377 value_[0] = '\0'; | 355 value_[0] = '\0'; |
| 378 value_size_ = 0; | 356 value_size_ = 0; |
| 379 return false; | 357 return false; |
| 380 } | 358 } |
| 381 | 359 |
| 382 // RegistryKeyIterator -------------------------------------------------------- | 360 // RegistryKeyIterator -------------------------------------------------------- |
| 383 | 361 |
| 384 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, | 362 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, |
| 385 const wchar_t* folder_key) { | 363 const wchar_t* folder_key) { |
| 386 base::ThreadRestrictions::AssertIOAllowed(); | |
| 387 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 364 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
| 388 if (result != ERROR_SUCCESS) { | 365 if (result != ERROR_SUCCESS) { |
| 389 key_ = NULL; | 366 key_ = NULL; |
| 390 } else { | 367 } else { |
| 391 DWORD count = 0; | 368 DWORD count = 0; |
| 392 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 369 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
| 393 NULL, NULL, NULL, NULL, NULL); | 370 NULL, NULL, NULL, NULL, NULL); |
| 394 | 371 |
| 395 if (result != ERROR_SUCCESS) { | 372 if (result != ERROR_SUCCESS) { |
| 396 ::RegCloseKey(key_); | 373 ::RegCloseKey(key_); |
| 397 key_ = NULL; | 374 key_ = NULL; |
| 398 } else { | 375 } else { |
| 399 index_ = count - 1; | 376 index_ = count - 1; |
| 400 } | 377 } |
| 401 } | 378 } |
| 402 | 379 |
| 403 Read(); | 380 Read(); |
| 404 } | 381 } |
| 405 | 382 |
| 406 RegistryKeyIterator::~RegistryKeyIterator() { | 383 RegistryKeyIterator::~RegistryKeyIterator() { |
| 407 base::ThreadRestrictions::AssertIOAllowed(); | |
| 408 if (key_) | 384 if (key_) |
| 409 ::RegCloseKey(key_); | 385 ::RegCloseKey(key_); |
| 410 } | 386 } |
| 411 | 387 |
| 412 DWORD RegistryKeyIterator::SubkeyCount() const { | 388 DWORD RegistryKeyIterator::SubkeyCount() const { |
| 413 base::ThreadRestrictions::AssertIOAllowed(); | |
| 414 DWORD count = 0; | 389 DWORD count = 0; |
| 415 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 390 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
| 416 NULL, NULL, NULL, NULL, NULL); | 391 NULL, NULL, NULL, NULL, NULL); |
| 417 if (result != ERROR_SUCCESS) | 392 if (result != ERROR_SUCCESS) |
| 418 return 0; | 393 return 0; |
| 419 | 394 |
| 420 return count; | 395 return count; |
| 421 } | 396 } |
| 422 | 397 |
| 423 bool RegistryKeyIterator::Valid() const { | 398 bool RegistryKeyIterator::Valid() const { |
| 424 return key_ != NULL && index_ >= 0; | 399 return key_ != NULL && index_ >= 0; |
| 425 } | 400 } |
| 426 | 401 |
| 427 void RegistryKeyIterator::operator++() { | 402 void RegistryKeyIterator::operator++() { |
| 428 --index_; | 403 --index_; |
| 429 Read(); | 404 Read(); |
| 430 } | 405 } |
| 431 | 406 |
| 432 bool RegistryKeyIterator::Read() { | 407 bool RegistryKeyIterator::Read() { |
| 433 base::ThreadRestrictions::AssertIOAllowed(); | |
| 434 if (Valid()) { | 408 if (Valid()) { |
| 435 DWORD ncount = arraysize(name_); | 409 DWORD ncount = arraysize(name_); |
| 436 FILETIME written; | 410 FILETIME written; |
| 437 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, | 411 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, |
| 438 NULL, &written); | 412 NULL, &written); |
| 439 if (ERROR_SUCCESS == r) | 413 if (ERROR_SUCCESS == r) |
| 440 return true; | 414 return true; |
| 441 } | 415 } |
| 442 | 416 |
| 443 name_[0] = '\0'; | 417 name_[0] = '\0'; |
| 444 return false; | 418 return false; |
| 445 } | 419 } |
| 446 | 420 |
| 447 } // namespace win | 421 } // namespace win |
| 448 } // namespace base | 422 } // namespace base |
| OLD | NEW |