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