| Index: base/win/registry.cc
|
| diff --git a/base/win/registry.cc b/base/win/registry.cc
|
| index a6cb9ae89f789a78461e7d611374e603f492b724..fb07f17b567f5ffa7ef7a165747f11d1ed80ca62 100644
|
| --- a/base/win/registry.cc
|
| +++ b/base/win/registry.cc
|
| @@ -36,21 +36,14 @@ const REGSAM kWow64AccessMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY;
|
|
|
| // RegKey ----------------------------------------------------------------------
|
|
|
| -RegKey::RegKey()
|
| - : key_(NULL),
|
| - watch_event_(0),
|
| - wow64access_(0) {
|
| +RegKey::RegKey() : key_(NULL), wow64access_(0) {
|
| }
|
|
|
| -RegKey::RegKey(HKEY key)
|
| - : key_(key),
|
| - watch_event_(0),
|
| - wow64access_(0) {
|
| +RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {
|
| }
|
|
|
| RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
|
| : key_(NULL),
|
| - watch_event_(0),
|
| wow64access_(0) {
|
| if (rootkey) {
|
| if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
|
| @@ -150,7 +143,6 @@ LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) {
|
| }
|
|
|
| void RegKey::Close() {
|
| - StopWatching();
|
| if (key_) {
|
| ::RegCloseKey(key_);
|
| key_ = NULL;
|
| @@ -168,7 +160,6 @@ void RegKey::Set(HKEY key) {
|
|
|
| HKEY RegKey::Take() {
|
| DCHECK(wow64access_ == 0);
|
| - StopWatching();
|
| HKEY key = key_;
|
| key_ = NULL;
|
| return key;
|
| @@ -367,10 +358,32 @@ LONG RegKey::WriteValue(const wchar_t* name,
|
| return result;
|
| }
|
|
|
| -LONG RegKey::StartWatching() {
|
| +bool RegKey::StartWatching(const ChangeCallback& callback) {
|
| + DCHECK(callback_.is_null());
|
| + if (!StartWatchingInternal())
|
| + return false;
|
| +
|
| + DCHECK(watch_event_.IsValid());
|
| + if (!object_watcher_.StartWatching(watch_event_.Get(), this))
|
| + return false;
|
| +
|
| + callback_ = callback;
|
| + return true;
|
| +}
|
| +
|
| +bool RegKey::StartWatchingInternal() {
|
| DCHECK(key_);
|
| - if (!watch_event_)
|
| - watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
|
| + if (GetVersion() < VERSION_VISTA) {
|
| + // It is an error to register multiple times before Vista.
|
| + if (watch_event_.IsValid())
|
| + return true;
|
| + }
|
| +
|
| + if (!watch_event_.IsValid())
|
| + watch_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
|
| +
|
| + if (!watch_event_.IsValid())
|
| + return false;
|
|
|
| DWORD filter = REG_NOTIFY_CHANGE_NAME |
|
| REG_NOTIFY_CHANGE_ATTRIBUTES |
|
| @@ -378,33 +391,14 @@ LONG RegKey::StartWatching() {
|
| REG_NOTIFY_CHANGE_SECURITY;
|
|
|
| // Watch the registry key for a change of value.
|
| - LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE);
|
| + LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_.Get(),
|
| + TRUE);
|
| if (result != ERROR_SUCCESS) {
|
| - CloseHandle(watch_event_);
|
| - watch_event_ = 0;
|
| - }
|
| -
|
| - return result;
|
| -}
|
| -
|
| -bool RegKey::HasChanged() {
|
| - if (watch_event_) {
|
| - if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) {
|
| - StartWatching();
|
| - return true;
|
| - }
|
| + watch_event_.Close();
|
| + return false;
|
| }
|
| - return false;
|
| -}
|
|
|
| -LONG RegKey::StopWatching() {
|
| - LONG result = ERROR_INVALID_HANDLE;
|
| - if (watch_event_) {
|
| - CloseHandle(watch_event_);
|
| - watch_event_ = 0;
|
| - result = ERROR_SUCCESS;
|
| - }
|
| - return result;
|
| + return true;
|
| }
|
|
|
| // static
|
| @@ -484,6 +478,13 @@ LONG RegKey::RegDelRecurse(HKEY root_key,
|
| return result;
|
| }
|
|
|
| +void RegKey::OnObjectSignaled(HANDLE object) {
|
| + DCHECK(watch_event_.IsValid() && watch_event_.Get() == object);
|
| + ChangeCallback callback = callback_;
|
| + callback_.Reset();
|
| + callback.Run();
|
| +}
|
| +
|
| // RegistryValueIterator ------------------------------------------------------
|
|
|
| RegistryValueIterator::RegistryValueIterator(HKEY root_key,
|
|
|