| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 Open(rootkey, subkey, access); | 32 Open(rootkey, subkey, access); |
| 33 } else { | 33 } else { |
| 34 DCHECK(!subkey); | 34 DCHECK(!subkey); |
| 35 } | 35 } |
| 36 } | 36 } |
| 37 | 37 |
| 38 RegKey::~RegKey() { | 38 RegKey::~RegKey() { |
| 39 Close(); | 39 Close(); |
| 40 } | 40 } |
| 41 | 41 |
| 42 bool RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { | 42 GONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
| 43 DWORD disposition_value; | 43 DWORD disposition_value; |
| 44 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); | 44 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); |
| 45 } | 45 } |
| 46 | 46 |
| 47 bool RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, | 47 GONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, |
| 48 DWORD* disposition, REGSAM access) { | 48 DWORD* disposition, REGSAM access) { |
| 49 base::ThreadRestrictions::AssertIOAllowed(); | 49 base::ThreadRestrictions::AssertIOAllowed(); |
| 50 DCHECK(rootkey && subkey && access && disposition); | 50 DCHECK(rootkey && subkey && access && disposition); |
| 51 Close(); | 51 Close(); |
| 52 | 52 |
| 53 LONG result = RegCreateKeyEx(rootkey, | 53 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL, |
| 54 subkey, | 54 REG_OPTION_NON_VOLATILE, access, NULL, &key_, |
| 55 0, | |
| 56 NULL, | |
| 57 REG_OPTION_NON_VOLATILE, | |
| 58 access, | |
| 59 NULL, | |
| 60 &key_, | |
| 61 disposition); | 55 disposition); |
| 62 if (result != ERROR_SUCCESS) { | 56 return result; |
| 63 key_ = NULL; | |
| 64 return false; | |
| 65 } | |
| 66 | |
| 67 return true; | |
| 68 } | 57 } |
| 69 | 58 |
| 70 bool RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { | 59 GONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
| 71 base::ThreadRestrictions::AssertIOAllowed(); | 60 base::ThreadRestrictions::AssertIOAllowed(); |
| 72 DCHECK(rootkey && subkey && access); | 61 DCHECK(rootkey && subkey && access); |
| 73 Close(); | 62 Close(); |
| 74 | 63 |
| 75 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); | 64 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); |
| 76 if (result != ERROR_SUCCESS) { | 65 return result; |
| 77 key_ = NULL; | |
| 78 return false; | |
| 79 } | |
| 80 return true; | |
| 81 } | 66 } |
| 82 | 67 |
| 83 bool RegKey::CreateKey(const wchar_t* name, REGSAM access) { | 68 GONG RegKey::CreateKey(const wchar_t* name, REGSAM access) { |
| 84 base::ThreadRestrictions::AssertIOAllowed(); | 69 base::ThreadRestrictions::AssertIOAllowed(); |
| 85 DCHECK(name && access); | 70 DCHECK(name && access); |
| 86 | 71 |
| 87 HKEY subkey = NULL; | 72 HKEY subkey = NULL; |
| 88 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, | 73 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, |
| 89 access, NULL, &subkey, NULL); | 74 access, NULL, &subkey, NULL); |
| 90 Close(); | 75 Close(); |
| 91 | 76 |
| 92 key_ = subkey; | 77 key_ = subkey; |
| 93 return (result == ERROR_SUCCESS); | 78 return result; |
| 94 } | 79 } |
| 95 | 80 |
| 96 bool RegKey::OpenKey(const wchar_t* name, REGSAM access) { | 81 GONG RegKey::OpenKey(const wchar_t* name, REGSAM access) { |
| 97 base::ThreadRestrictions::AssertIOAllowed(); | 82 base::ThreadRestrictions::AssertIOAllowed(); |
| 98 DCHECK(name && access); | 83 DCHECK(name && access); |
| 99 | 84 |
| 100 HKEY subkey = NULL; | 85 HKEY subkey = NULL; |
| 101 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); | 86 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); |
| 102 | 87 |
| 103 Close(); | 88 Close(); |
| 104 | 89 |
| 105 key_ = subkey; | 90 key_ = subkey; |
| 106 return (result == ERROR_SUCCESS); | 91 return result; |
| 107 } | 92 } |
| 108 | 93 |
| 109 void RegKey::Close() { | 94 void RegKey::Close() { |
| 110 base::ThreadRestrictions::AssertIOAllowed(); | 95 base::ThreadRestrictions::AssertIOAllowed(); |
| 111 StopWatching(); | 96 StopWatching(); |
| 112 if (key_) { | 97 if (key_) { |
| 113 ::RegCloseKey(key_); | 98 ::RegCloseKey(key_); |
| 114 key_ = NULL; | 99 key_ = NULL; |
| 115 } | 100 } |
| 116 } | 101 } |
| 117 | 102 |
| 118 DWORD RegKey::ValueCount() const { | 103 DWORD RegKey::ValueCount() const { |
| 119 base::ThreadRestrictions::AssertIOAllowed(); | 104 base::ThreadRestrictions::AssertIOAllowed(); |
| 120 DWORD count = 0; | 105 DWORD count = 0; |
| 121 HRESULT result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, | 106 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, |
| 122 NULL, &count, NULL, NULL, NULL, NULL); | 107 NULL, NULL, NULL, NULL); |
| 123 return (result != ERROR_SUCCESS) ? 0 : count; | 108 return (result != ERROR_SUCCESS) ? 0 : count; |
| 124 } | 109 } |
| 125 | 110 |
| 126 bool RegKey::ReadName(int index, std::wstring* name) const { | 111 GONG RegKey::ReadName(int index, std::wstring* name) const { |
| 127 base::ThreadRestrictions::AssertIOAllowed(); | 112 base::ThreadRestrictions::AssertIOAllowed(); |
| 128 wchar_t buf[256]; | 113 wchar_t buf[256]; |
| 129 DWORD bufsize = arraysize(buf); | 114 DWORD bufsize = arraysize(buf); |
| 130 LRESULT r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, | 115 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL); |
| 131 NULL, NULL); | 116 if (r == ERROR_SUCCESS) |
| 132 if (r != ERROR_SUCCESS) | |
| 133 return false; | |
| 134 if (name) | |
| 135 *name = buf; | 117 *name = buf; |
| 136 return true; | 118 |
| 119 return r; |
| 137 } | 120 } |
| 138 | 121 |
| 139 bool RegKey::DeleteKey(const wchar_t* name) { | 122 GONG RegKey::DeleteKey(const wchar_t* name) { |
| 140 base::ThreadRestrictions::AssertIOAllowed(); | 123 base::ThreadRestrictions::AssertIOAllowed(); |
| 141 if (!key_) | 124 DCHECK(key_); |
| 142 return false; | 125 DCHECK(name); |
| 143 LSTATUS ret = SHDeleteKey(key_, name); | 126 LONG result = SHDeleteKey(key_, name); |
| 144 if (ERROR_SUCCESS != ret) | 127 return result; |
| 145 SetLastError(ret); | |
| 146 return ERROR_SUCCESS == ret; | |
| 147 } | 128 } |
| 148 | 129 |
| 149 bool RegKey::DeleteValue(const wchar_t* value_name) { | 130 GONG RegKey::DeleteValue(const wchar_t* value_name) { |
| 150 base::ThreadRestrictions::AssertIOAllowed(); | 131 base::ThreadRestrictions::AssertIOAllowed(); |
| 132 DCHECK(key_); |
| 151 DCHECK(value_name); | 133 DCHECK(value_name); |
| 152 HRESULT result = RegDeleteValue(key_, value_name); | 134 LONG result = RegDeleteValue(key_, value_name); |
| 153 return (result == ERROR_SUCCESS); | 135 return result; |
| 154 } | 136 } |
| 155 | 137 |
| 156 bool RegKey::ValueExists(const wchar_t* name) { | 138 bool RegKey::ValueExists(const wchar_t* name) const { |
| 157 base::ThreadRestrictions::AssertIOAllowed(); | 139 base::ThreadRestrictions::AssertIOAllowed(); |
| 158 if (!key_) | 140 LONG result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); |
| 159 return false; | 141 return result == ERROR_SUCCESS; |
| 160 HRESULT result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); | |
| 161 return (result == ERROR_SUCCESS); | |
| 162 } | 142 } |
| 163 | 143 |
| 164 bool RegKey::ReadValue(const wchar_t* name, void* data, | 144 GONG RegKey::ReadValue(const wchar_t* name, void* data, DWORD* dsize, |
| 165 DWORD* dsize, DWORD* dtype) const { | 145 DWORD* dtype) const { |
| 166 base::ThreadRestrictions::AssertIOAllowed(); | 146 base::ThreadRestrictions::AssertIOAllowed(); |
| 167 if (!key_) | 147 LONG result = RegQueryValueEx(key_, name, 0, dtype, |
| 168 return false; | 148 reinterpret_cast<LPBYTE>(data), dsize); |
| 169 HRESULT result = RegQueryValueEx(key_, name, 0, dtype, | 149 return result; |
| 170 reinterpret_cast<LPBYTE>(data), dsize); | |
| 171 return (result == ERROR_SUCCESS); | |
| 172 } | 150 } |
| 173 | 151 |
| 174 bool RegKey::ReadValue(const wchar_t* name, std::wstring* value) const { | 152 GONG RegKey::ReadValue(const wchar_t* name, std::wstring* value) const { |
| 175 base::ThreadRestrictions::AssertIOAllowed(); | 153 base::ThreadRestrictions::AssertIOAllowed(); |
| 176 DCHECK(value); | 154 DCHECK(value); |
| 177 const size_t kMaxStringLength = 1024; // This is after expansion. | 155 const size_t kMaxStringLength = 1024; // This is after expansion. |
| 178 // Use the one of the other forms of ReadValue if 1024 is too small for you. | 156 // Use the one of the other forms of ReadValue if 1024 is too small for you. |
| 179 wchar_t raw_value[kMaxStringLength]; | 157 wchar_t raw_value[kMaxStringLength]; |
| 180 DWORD type = REG_SZ, size = sizeof(raw_value); | 158 DWORD type = REG_SZ, size = sizeof(raw_value); |
| 181 if (ReadValue(name, raw_value, &size, &type)) { | 159 LONG result = ReadValue(name, raw_value, &size, &type); |
| 160 if (result == ERROR_SUCCESS) { |
| 182 if (type == REG_SZ) { | 161 if (type == REG_SZ) { |
| 183 *value = raw_value; | 162 *value = raw_value; |
| 184 } else if (type == REG_EXPAND_SZ) { | 163 } else if (type == REG_EXPAND_SZ) { |
| 185 wchar_t expanded[kMaxStringLength]; | 164 wchar_t expanded[kMaxStringLength]; |
| 186 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); | 165 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); |
| 187 // Success: returns the number of wchar_t's copied | 166 // Success: returns the number of wchar_t's copied |
| 188 // Fail: buffer too small, returns the size required | 167 // Fail: buffer too small, returns the size required |
| 189 // Fail: other, returns 0 | 168 // Fail: other, returns 0 |
| 190 if (size == 0 || size > kMaxStringLength) | 169 if (size == 0 || size > kMaxStringLength) { |
| 191 return false; | 170 result = ERROR_MORE_DATA; |
| 192 *value = expanded; | 171 } else { |
| 172 *value = expanded; |
| 173 } |
| 193 } else { | 174 } else { |
| 194 // Not a string. Oops. | 175 // Not a string. Oops. |
| 195 return false; | 176 result = ERROR_CANTREAD; |
| 196 } | 177 } |
| 197 return true; | |
| 198 } | 178 } |
| 199 | 179 |
| 200 return false; | 180 return result; |
| 201 } | 181 } |
| 202 | 182 |
| 203 bool RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const { | 183 GONG RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const { |
| 204 DCHECK(value); | 184 DCHECK(value); |
| 205 DWORD type = REG_DWORD; | 185 DWORD type = REG_DWORD; |
| 206 DWORD size = sizeof(DWORD); | 186 DWORD size = sizeof(DWORD); |
| 207 DWORD result = 0; | 187 DWORD local_value = 0; |
| 208 if (ReadValue(name, &result, &size, &type) && | 188 LONG result = ReadValue(name, &local_value, &size, &type); |
| 209 (type == REG_DWORD || type == REG_BINARY) && | 189 if (result == ERROR_SUCCESS) { |
| 210 size == sizeof(DWORD)) { | 190 if ((type == REG_DWORD || type == REG_BINARY) && size == sizeof(DWORD)) { |
| 211 *value = result; | 191 *value = local_value; |
| 212 return true; | 192 } else { |
| 193 result = ERROR_CANTREAD; |
| 194 } |
| 213 } | 195 } |
| 214 | 196 |
| 215 return false; | 197 return result; |
| 216 } | 198 } |
| 217 | 199 |
| 218 bool RegKey::WriteValue(const wchar_t* name, const void * data, | 200 GONG RegKey::ReadInt64(const wchar_t* name, int64* value) const { |
| 201 DCHECK(value); |
| 202 DWORD type = REG_QWORD; |
| 203 int64 local_value = 0; |
| 204 DWORD size = sizeof(local_value); |
| 205 LONG result = ReadValue(name, &local_value, &size, &type); |
| 206 if (result == ERROR_SUCCESS) { |
| 207 if ((type == REG_QWORD || type == REG_BINARY) && |
| 208 size == sizeof(local_value)) { |
| 209 *value = local_value; |
| 210 } else { |
| 211 result = ERROR_CANTREAD; |
| 212 } |
| 213 } |
| 214 |
| 215 return result; |
| 216 } |
| 217 |
| 218 GONG RegKey::WriteValue(const wchar_t* name, const void * data, |
| 219 DWORD dsize, DWORD dtype) { | 219 DWORD dsize, DWORD dtype) { |
| 220 base::ThreadRestrictions::AssertIOAllowed(); | 220 base::ThreadRestrictions::AssertIOAllowed(); |
| 221 DCHECK(data); | 221 DCHECK(data); |
| 222 DCHECK(key_); |
| 222 | 223 |
| 223 if (!key_) | 224 LONG result = RegSetValueEx(key_, name, 0, dtype, |
| 224 return false; | 225 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); |
| 225 | 226 return result; |
| 226 HRESULT result = RegSetValueEx( | |
| 227 key_, | |
| 228 name, | |
| 229 0, | |
| 230 dtype, | |
| 231 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), | |
| 232 dsize); | |
| 233 return (result == ERROR_SUCCESS); | |
| 234 } | 227 } |
| 235 | 228 |
| 236 bool RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { | 229 GONG RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { |
| 237 return WriteValue(name, value, | 230 return WriteValue(name, value, |
| 238 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); | 231 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); |
| 239 } | 232 } |
| 240 | 233 |
| 241 bool RegKey::WriteValue(const wchar_t* name, DWORD value) { | 234 GONG RegKey::WriteValue(const wchar_t* name, DWORD value) { |
| 242 return WriteValue(name, &value, | 235 return WriteValue(name, &value, static_cast<DWORD>(sizeof(value)), REG_DWORD); |
| 243 static_cast<DWORD>(sizeof(value)), REG_DWORD); | |
| 244 } | 236 } |
| 245 | 237 |
| 246 bool RegKey::StartWatching() { | 238 GONG RegKey::StartWatching() { |
| 239 DCHECK(key_); |
| 247 if (!watch_event_) | 240 if (!watch_event_) |
| 248 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); | 241 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); |
| 249 | 242 |
| 250 DWORD filter = REG_NOTIFY_CHANGE_NAME | | 243 DWORD filter = REG_NOTIFY_CHANGE_NAME | |
| 251 REG_NOTIFY_CHANGE_ATTRIBUTES | | 244 REG_NOTIFY_CHANGE_ATTRIBUTES | |
| 252 REG_NOTIFY_CHANGE_LAST_SET | | 245 REG_NOTIFY_CHANGE_LAST_SET | |
| 253 REG_NOTIFY_CHANGE_SECURITY; | 246 REG_NOTIFY_CHANGE_SECURITY; |
| 254 | 247 |
| 255 // Watch the registry key for a change of value. | 248 // Watch the registry key for a change of value. |
| 256 HRESULT result = RegNotifyChangeKeyValue(key_, TRUE, filter, | 249 LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE); |
| 257 watch_event_, TRUE); | 250 if (result != ERROR_SUCCESS) { |
| 258 if (SUCCEEDED(result)) { | |
| 259 return true; | |
| 260 } else { | |
| 261 CloseHandle(watch_event_); | 251 CloseHandle(watch_event_); |
| 262 watch_event_ = 0; | 252 watch_event_ = 0; |
| 263 return false; | |
| 264 } | 253 } |
| 254 |
| 255 return result; |
| 265 } | 256 } |
| 266 | 257 |
| 267 bool RegKey::HasChanged() { | 258 bool RegKey::HasChanged() { |
| 268 if (watch_event_) { | 259 if (watch_event_) { |
| 269 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { | 260 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { |
| 270 StartWatching(); | 261 StartWatching(); |
| 271 return true; | 262 return true; |
| 272 } | 263 } |
| 273 } | 264 } |
| 274 return false; | 265 return false; |
| 275 } | 266 } |
| 276 | 267 |
| 277 bool RegKey::StopWatching() { | 268 GONG RegKey::StopWatching() { |
| 269 LONG result = ERROR_INVALID_HANDLE; |
| 278 if (watch_event_) { | 270 if (watch_event_) { |
| 279 CloseHandle(watch_event_); | 271 CloseHandle(watch_event_); |
| 280 watch_event_ = 0; | 272 watch_event_ = 0; |
| 281 return true; | 273 result = ERROR_SUCCESS; |
| 282 } | 274 } |
| 283 return false; | 275 return result; |
| 284 } | 276 } |
| 285 | 277 |
| 286 // RegistryValueIterator ------------------------------------------------------ | 278 // RegistryValueIterator ------------------------------------------------------ |
| 287 | 279 |
| 288 RegistryValueIterator::RegistryValueIterator(HKEY root_key, | 280 RegistryValueIterator::RegistryValueIterator(HKEY root_key, |
| 289 const wchar_t* folder_key) { | 281 const wchar_t* folder_key) { |
| 290 base::ThreadRestrictions::AssertIOAllowed(); | 282 base::ThreadRestrictions::AssertIOAllowed(); |
| 291 | 283 |
| 292 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 284 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
| 293 if (result != ERROR_SUCCESS) { | 285 if (result != ERROR_SUCCESS) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 310 | 302 |
| 311 RegistryValueIterator::~RegistryValueIterator() { | 303 RegistryValueIterator::~RegistryValueIterator() { |
| 312 base::ThreadRestrictions::AssertIOAllowed(); | 304 base::ThreadRestrictions::AssertIOAllowed(); |
| 313 if (key_) | 305 if (key_) |
| 314 ::RegCloseKey(key_); | 306 ::RegCloseKey(key_); |
| 315 } | 307 } |
| 316 | 308 |
| 317 DWORD RegistryValueIterator::ValueCount() const { | 309 DWORD RegistryValueIterator::ValueCount() const { |
| 318 base::ThreadRestrictions::AssertIOAllowed(); | 310 base::ThreadRestrictions::AssertIOAllowed(); |
| 319 DWORD count = 0; | 311 DWORD count = 0; |
| 320 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, | 312 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, |
| 321 &count, NULL, NULL, NULL, NULL); | 313 &count, NULL, NULL, NULL, NULL); |
| 322 | |
| 323 if (result != ERROR_SUCCESS) | 314 if (result != ERROR_SUCCESS) |
| 324 return 0; | 315 return 0; |
| 325 | 316 |
| 326 return count; | 317 return count; |
| 327 } | 318 } |
| 328 | 319 |
| 329 bool RegistryValueIterator::Valid() const { | 320 bool RegistryValueIterator::Valid() const { |
| 330 return key_ != NULL && index_ >= 0; | 321 return key_ != NULL && index_ >= 0; |
| 331 } | 322 } |
| 332 | 323 |
| 333 void RegistryValueIterator::operator++() { | 324 void RegistryValueIterator::operator++() { |
| 334 --index_; | 325 --index_; |
| 335 Read(); | 326 Read(); |
| 336 } | 327 } |
| 337 | 328 |
| 338 bool RegistryValueIterator::Read() { | 329 bool RegistryValueIterator::Read() { |
| 339 base::ThreadRestrictions::AssertIOAllowed(); | 330 base::ThreadRestrictions::AssertIOAllowed(); |
| 340 if (Valid()) { | 331 if (Valid()) { |
| 341 DWORD ncount = arraysize(name_); | 332 DWORD ncount = arraysize(name_); |
| 342 value_size_ = sizeof(value_); | 333 value_size_ = sizeof(value_); |
| 343 LRESULT r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, | 334 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, |
| 344 reinterpret_cast<BYTE*>(value_), &value_size_); | 335 reinterpret_cast<BYTE*>(value_), &value_size_); |
| 345 if (ERROR_SUCCESS == r) | 336 if (ERROR_SUCCESS == r) |
| 346 return true; | 337 return true; |
| 347 } | 338 } |
| 348 | 339 |
| 349 name_[0] = '\0'; | 340 name_[0] = '\0'; |
| 350 value_[0] = '\0'; | 341 value_[0] = '\0'; |
| 351 value_size_ = 0; | 342 value_size_ = 0; |
| 352 return false; | 343 return false; |
| 353 } | 344 } |
| 354 | 345 |
| 355 // RegistryKeyIterator -------------------------------------------------------- | 346 // RegistryKeyIterator -------------------------------------------------------- |
| 356 | 347 |
| 357 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, | 348 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, |
| 358 const wchar_t* folder_key) { | 349 const wchar_t* folder_key) { |
| 359 base::ThreadRestrictions::AssertIOAllowed(); | 350 base::ThreadRestrictions::AssertIOAllowed(); |
| 360 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 351 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
| 361 if (result != ERROR_SUCCESS) { | 352 if (result != ERROR_SUCCESS) { |
| 362 key_ = NULL; | 353 key_ = NULL; |
| 363 } else { | 354 } else { |
| 364 DWORD count = 0; | 355 DWORD count = 0; |
| 365 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 356 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
| 366 NULL, NULL, NULL, NULL, NULL); | 357 NULL, NULL, NULL, NULL, NULL); |
| 367 | 358 |
| 368 if (result != ERROR_SUCCESS) { | 359 if (result != ERROR_SUCCESS) { |
| 369 ::RegCloseKey(key_); | 360 ::RegCloseKey(key_); |
| 370 key_ = NULL; | 361 key_ = NULL; |
| 371 } else { | 362 } else { |
| 372 index_ = count - 1; | 363 index_ = count - 1; |
| 373 } | 364 } |
| 374 } | 365 } |
| 375 | 366 |
| 376 Read(); | 367 Read(); |
| 377 } | 368 } |
| 378 | 369 |
| 379 RegistryKeyIterator::~RegistryKeyIterator() { | 370 RegistryKeyIterator::~RegistryKeyIterator() { |
| 380 base::ThreadRestrictions::AssertIOAllowed(); | 371 base::ThreadRestrictions::AssertIOAllowed(); |
| 381 if (key_) | 372 if (key_) |
| 382 ::RegCloseKey(key_); | 373 ::RegCloseKey(key_); |
| 383 } | 374 } |
| 384 | 375 |
| 385 DWORD RegistryKeyIterator::SubkeyCount() const { | 376 DWORD RegistryKeyIterator::SubkeyCount() const { |
| 386 base::ThreadRestrictions::AssertIOAllowed(); | 377 base::ThreadRestrictions::AssertIOAllowed(); |
| 387 DWORD count = 0; | 378 DWORD count = 0; |
| 388 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 379 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
| 389 NULL, NULL, NULL, NULL, NULL); | 380 NULL, NULL, NULL, NULL, NULL); |
| 390 | |
| 391 if (result != ERROR_SUCCESS) | 381 if (result != ERROR_SUCCESS) |
| 392 return 0; | 382 return 0; |
| 393 | 383 |
| 394 return count; | 384 return count; |
| 395 } | 385 } |
| 396 | 386 |
| 397 bool RegistryKeyIterator::Valid() const { | 387 bool RegistryKeyIterator::Valid() const { |
| 398 return key_ != NULL && index_ >= 0; | 388 return key_ != NULL && index_ >= 0; |
| 399 } | 389 } |
| 400 | 390 |
| 401 void RegistryKeyIterator::operator++() { | 391 void RegistryKeyIterator::operator++() { |
| 402 --index_; | 392 --index_; |
| 403 Read(); | 393 Read(); |
| 404 } | 394 } |
| 405 | 395 |
| 406 bool RegistryKeyIterator::Read() { | 396 bool RegistryKeyIterator::Read() { |
| 407 base::ThreadRestrictions::AssertIOAllowed(); | 397 base::ThreadRestrictions::AssertIOAllowed(); |
| 408 if (Valid()) { | 398 if (Valid()) { |
| 409 DWORD ncount = arraysize(name_); | 399 DWORD ncount = arraysize(name_); |
| 410 FILETIME written; | 400 FILETIME written; |
| 411 LRESULT r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, | 401 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, |
| 412 NULL, &written); | 402 NULL, &written); |
| 413 if (ERROR_SUCCESS == r) | 403 if (ERROR_SUCCESS == r) |
| 414 return true; | 404 return true; |
| 415 } | 405 } |
| 416 | 406 |
| 417 name_[0] = '\0'; | 407 name_[0] = '\0'; |
| 418 return false; | 408 return false; |
| 419 } | 409 } |
| 420 | 410 |
| 421 } // namespace win | 411 } // namespace win |
| 422 } // namespace base | 412 } // namespace base |
| OLD | NEW |