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
3 // found in the LICENSE file.
5 // A utility class that makes it easy to register for registry change
9 #include "chrome_frame/registry_watcher.h"
11 #include "chrome_frame/chrome_frame_helper_util.h"
14 const wchar_t kRegistryWatcherEventName
[] = L
"chrome_registry_watcher_event";
17 RegistryWatcher::RegistryWatcher(HKEY hive
,
20 : callback_(callback
),
24 // Enforce that we can open the given registry path with the KEY_NOTIFY
26 LONG result
= RegOpenKeyEx(hive
, path
, 0, KEY_NOTIFY
, ®istry_key_
);
27 if (result
!= ERROR_SUCCESS
) {
32 RegistryWatcher::~RegistryWatcher() {
35 RegCloseKey(registry_key_
);
40 bool RegistryWatcher::StartWatching() {
41 if (!registry_key_
|| wait_event_
|| !callback_
) {
46 wait_event_
= CreateEvent(NULL
,
48 FALSE
, // Initially non-signalled
49 kRegistryWatcherEventName
);
50 if (wait_event_
!= NULL
) {
51 LONG notify_result
= RegNotifyChangeKeyValue(
53 TRUE
, // Watch subtree
54 REG_NOTIFY_CHANGE_NAME
, // Notifies if a subkey is added.
56 TRUE
); // Asynchronous, signal the event when a change occurs.
58 if (notify_result
== ERROR_SUCCESS
) {
59 if (RegisterWaitForSingleObject(&wait_handle_
,
61 &RegistryWatcher::WaitCallback
,
62 reinterpret_cast<void*>(this),
71 // If we're not good to go we don't need to hold onto the event.
72 if (!result
&& wait_event_
) {
73 CloseHandle(wait_event_
);
80 void RegistryWatcher::StopWatching() {
83 // Unregister the wait and block until any current handlers have returned.
84 UnregisterWaitEx(wait_handle_
, INVALID_HANDLE_VALUE
);
88 CloseHandle(wait_event_
);
93 void CALLBACK
RegistryWatcher::WaitCallback(void* param
, BOOLEAN wait_fired
) {
94 RegistryWatcher
* watcher
= reinterpret_cast<RegistryWatcher
*>(param
);
95 if (watcher
->stopping_
)
98 if (watcher
->callback_
) {