Index: chrome/browser/policy/configuration_policy_provider_win.cc |
diff --git a/chrome/browser/policy/configuration_policy_provider_win.cc b/chrome/browser/policy/configuration_policy_provider_win.cc |
index 084f13093b14fabc81eabdbbef50236d36fa928e..df336d31172f0b6a09509ebc087b292ebb736d4f 100644 |
--- a/chrome/browser/policy/configuration_policy_provider_win.cc |
+++ b/chrome/browser/policy/configuration_policy_provider_win.cc |
@@ -4,290 +4,22 @@ |
#include "chrome/browser/policy/configuration_policy_provider_win.h" |
-#include <userenv.h> |
- |
-#include <algorithm> |
- |
-#include "base/logging.h" |
-#include "base/object_watcher.h" |
-#include "base/scoped_ptr.h" |
-#include "base/string_number_conversions.h" |
-#include "base/string_piece.h" |
-#include "base/string_util.h" |
-#include "base/sys_string_conversions.h" |
-#include "base/thread_restrictions.h" |
-#include "base/utf_string_conversions.h" |
-#include "base/values.h" |
-#include "base/win/registry.h" |
-#include "chrome/common/policy_constants.h" |
- |
-using base::win::RegKey; |
+#include "chrome/browser/policy/asynchronous_policy_provider.h" |
+#include "chrome/browser/policy/configuration_policy_loader_win.h" |
+#include "chrome/browser/policy/configuration_policy_provider_delegate_win.h" |
namespace policy { |
-namespace { |
- |
-bool ReadRegistryStringValue(RegKey* key, const string16& name, |
- string16* result) { |
- DWORD value_size = 0; |
- DWORD key_type = 0; |
- scoped_array<uint8> buffer; |
- |
- if (!key->ReadValue(name.c_str(), 0, &value_size, &key_type)) |
- return false; |
- if (key_type != REG_SZ) |
- return false; |
- |
- // According to the Microsoft documentation, the string |
- // buffer may not be explicitly 0-terminated. Allocate a |
- // slightly larger buffer and pre-fill to zeros to guarantee |
- // the 0-termination. |
- buffer.reset(new uint8[value_size + 2]); |
- memset(buffer.get(), 0, value_size + 2); |
- key->ReadValue(name.c_str(), buffer.get(), &value_size, NULL); |
- result->assign(reinterpret_cast<const wchar_t*>(buffer.get())); |
- return true; |
-} |
- |
-} // namespace |
- |
// Period at which to run the reload task in case the group policy change |
// watchers fail. |
const int kReloadIntervalMinutes = 15; |
-ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher:: |
- GroupPolicyChangeWatcher( |
- base::WeakPtr<ConfigurationPolicyProviderWin> provider, |
- int reload_interval_minutes) |
- : provider_(provider), |
- user_policy_changed_event_(false, false), |
- machine_policy_changed_event_(false, false), |
- user_policy_watcher_failed_(false), |
- machine_policy_watcher_failed_(false), |
- reload_interval_minutes_(reload_interval_minutes), |
- reload_task_(NULL) { |
- if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) { |
- PLOG(WARNING) << "Failed to register user group policy notification"; |
- user_policy_watcher_failed_ = true; |
- } |
- if (!RegisterGPNotification(machine_policy_changed_event_.handle(), true)) { |
- PLOG(WARNING) << "Failed to register machine group policy notification."; |
- machine_policy_watcher_failed_ = true; |
- } |
-} |
- |
-ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher:: |
- ~GroupPolicyChangeWatcher() { |
- if (MessageLoop::current()) |
- MessageLoop::current()->RemoveDestructionObserver(this); |
- DCHECK(!reload_task_); |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::Start() { |
- MessageLoop::current()->AddDestructionObserver(this); |
- SetupWatches(); |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::Stop() { |
- user_policy_watcher_.StopWatching(); |
- machine_policy_watcher_.StopWatching(); |
- if (reload_task_) { |
- reload_task_->Cancel(); |
- reload_task_ = NULL; |
- } |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::SetupWatches() { |
- if (reload_task_) { |
- reload_task_->Cancel(); |
- reload_task_ = NULL; |
- } |
- |
- if (!user_policy_watcher_failed_) { |
- if (!user_policy_watcher_.GetWatchedObject() && |
- !user_policy_watcher_.StartWatching( |
- user_policy_changed_event_.handle(), this)) { |
- LOG(WARNING) << "Failed to start watch for user policy change event"; |
- user_policy_watcher_failed_ = true; |
- } |
- } |
- if (!machine_policy_watcher_failed_) { |
- if (!machine_policy_watcher_.GetWatchedObject() && |
- !machine_policy_watcher_.StartWatching( |
- machine_policy_changed_event_.handle(), this)) { |
- LOG(WARNING) << "Failed to start watch for machine policy change event"; |
- machine_policy_watcher_failed_ = true; |
- } |
- } |
- |
- if (user_policy_watcher_failed_ || machine_policy_watcher_failed_) { |
- reload_task_ = |
- NewRunnableMethod(this, &GroupPolicyChangeWatcher::ReloadFromTask); |
- int64 delay = |
- base::TimeDelta::FromMinutes(reload_interval_minutes_).InMilliseconds(); |
- MessageLoop::current()->PostDelayedTask(FROM_HERE, reload_task_, delay); |
- } |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher::Reload() { |
- if (provider_.get()) |
- provider_->NotifyStoreOfPolicyChange(); |
- SetupWatches(); |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher:: |
- ReloadFromTask() { |
- // Make sure to not call Cancel() on the task, since it might hold the last |
- // reference that keeps this object alive. |
- reload_task_ = NULL; |
- Reload(); |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher:: |
- OnObjectSignaled(HANDLE object) { |
- DCHECK(object == user_policy_changed_event_.handle() || |
- object == machine_policy_changed_event_.handle()) |
- << "unexpected object signaled policy reload, obj = " |
- << std::showbase << std::hex << object; |
- Reload(); |
-} |
- |
-void ConfigurationPolicyProviderWin::GroupPolicyChangeWatcher:: |
- WillDestroyCurrentMessageLoop() { |
- reload_task_ = NULL; |
- MessageLoop::current()->RemoveDestructionObserver(this); |
-} |
- |
ConfigurationPolicyProviderWin::ConfigurationPolicyProviderWin( |
const PolicyDefinitionList* policy_list) |
- : ConfigurationPolicyProvider(policy_list) { |
- watcher_ = new GroupPolicyChangeWatcher(this->AsWeakPtr(), |
- kReloadIntervalMinutes); |
- watcher_->Start(); |
-} |
- |
-ConfigurationPolicyProviderWin::~ConfigurationPolicyProviderWin() { |
- watcher_->Stop(); |
-} |
- |
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyString( |
- const string16& name, string16* result) const { |
- string16 path = string16(kRegistrySubKey); |
- RegKey policy_key; |
- // First try the global policy. |
- if (policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) { |
- if (ReadRegistryStringValue(&policy_key, name, result)) |
- return true; |
- policy_key.Close(); |
- } |
- // Fall back on user-specific policy. |
- if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ)) |
- return false; |
- return ReadRegistryStringValue(&policy_key, name, result); |
-} |
- |
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyStringList( |
- const string16& key, ListValue* result) const { |
- string16 path = string16(kRegistrySubKey); |
- path += ASCIIToUTF16("\\") + key; |
- RegKey policy_key; |
- if (!policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) { |
- policy_key.Close(); |
- // Fall back on user-specific policy. |
- if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ)) |
- return false; |
- } |
- string16 policy_string; |
- int index = 0; |
- while (ReadRegistryStringValue(&policy_key, base::IntToString16(++index), |
- &policy_string)) { |
- result->Append(Value::CreateStringValue(policy_string)); |
- } |
- return true; |
-} |
- |
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyBoolean( |
- const string16& value_name, bool* result) const { |
- DWORD value; |
- RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); |
- if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
- *result = value != 0; |
- return true; |
- } |
- |
- RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ); |
- if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
- *result = value != 0; |
- return true; |
- } |
- return false; |
-} |
- |
-bool ConfigurationPolicyProviderWin::GetRegistryPolicyInteger( |
- const string16& value_name, uint32* result) const { |
- DWORD value; |
- RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); |
- if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
- *result = value; |
- return true; |
- } |
- |
- RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ); |
- if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
- *result = value; |
- return true; |
- } |
- return false; |
-} |
- |
-bool ConfigurationPolicyProviderWin::Provide( |
- ConfigurationPolicyStoreInterface* store) { |
- // This function calls GetRegistryPolicy* which hit up the registry. Those |
- // are I/O functions not allowed to be called on the main thread. |
- // http://crbug.com/66453 |
- base::ThreadRestrictions::ScopedAllowIO allow_io; |
- const PolicyDefinitionList* policy_list(policy_definition_list()); |
- for (const PolicyDefinitionList::Entry* current = policy_list->begin; |
- current != policy_list->end; ++current) { |
- std::wstring name = UTF8ToWide(current->name); |
- switch (current->value_type) { |
- case Value::TYPE_STRING: { |
- std::wstring string_value; |
- if (GetRegistryPolicyString(name.c_str(), &string_value)) { |
- store->Apply(current->policy_type, |
- Value::CreateStringValue(string_value)); |
- } |
- break; |
- } |
- case Value::TYPE_LIST: { |
- scoped_ptr<ListValue> list_value(new ListValue); |
- if (GetRegistryPolicyStringList(name.c_str(), list_value.get())) |
- store->Apply(current->policy_type, list_value.release()); |
- break; |
- } |
- case Value::TYPE_BOOLEAN: { |
- bool bool_value; |
- if (GetRegistryPolicyBoolean(name.c_str(), &bool_value)) { |
- store->Apply(current->policy_type, |
- Value::CreateBooleanValue(bool_value)); |
- } |
- break; |
- } |
- case Value::TYPE_INTEGER: { |
- uint32 int_value; |
- if (GetRegistryPolicyInteger(name.c_str(), &int_value)) { |
- store->Apply(current->policy_type, |
- Value::CreateIntegerValue(int_value)); |
- } |
- break; |
- } |
- default: |
- NOTREACHED(); |
- return false; |
- } |
- } |
- |
- return true; |
-} |
+ : AsynchronousPolicyProvider( |
+ policy_list, |
+ new ConfigurationPolicyLoaderWin( |
+ new ConfigurationPolicyProviderDelegateWin(policy_list), |
+ kReloadIntervalMinutes)) {} |
} // namespace policy |