Index: chrome/browser/policy/configuration_policy_provider_delegate_win.cc |
diff --git a/chrome/browser/policy/configuration_policy_provider_delegate_win.cc b/chrome/browser/policy/configuration_policy_provider_delegate_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..68947dee892b277199c0cb2d498026d0d0938ca0 |
--- /dev/null |
+++ b/chrome/browser/policy/configuration_policy_provider_delegate_win.cc |
@@ -0,0 +1,160 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/policy/configuration_policy_provider_delegate_win.h" |
+ |
+#include "base/string_number_conversions.h" |
+#include "base/utf_string_conversions.h" |
+#include "base/win/registry.h" |
+#include "chrome/common/policy_constants.h" |
+ |
+using base::win::RegKey; |
+ |
+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 |
+ |
+namespace policy { |
+ |
+ConfigurationPolicyProviderDelegateWin::ConfigurationPolicyProviderDelegateWin( |
+ const ConfigurationPolicyProvider::PolicyDefinitionList* |
+ policy_definition_list) |
+ : policy_definition_list_(policy_definition_list) { |
+} |
+ |
+DictionaryValue* ConfigurationPolicyProviderDelegateWin::Load() { |
+ DictionaryValue* result = new DictionaryValue(); |
+ const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; |
+ for (current = policy_definition_list_->begin; |
+ current != policy_definition_list_->end; |
+ ++current) { |
+ const string16 name(ASCIIToUTF16(current->name)); |
+ switch (current->value_type) { |
+ case Value::TYPE_STRING: { |
+ string16 string_value; |
+ if (GetRegistryPolicyString(name, &string_value)) { |
+ result->SetString(current->name, string_value); |
+ } |
+ break; |
+ } |
+ case Value::TYPE_LIST: { |
+ scoped_ptr<ListValue> list_value(new ListValue); |
+ if (GetRegistryPolicyStringList(name, list_value.get())) |
+ result->Set(current->name, list_value.release()); |
+ break; |
+ } |
+ case Value::TYPE_BOOLEAN: { |
+ bool bool_value; |
+ if (GetRegistryPolicyBoolean(name, &bool_value)) { |
+ result->SetBoolean(current->name, bool_value); |
+ } |
+ break; |
+ } |
+ case Value::TYPE_INTEGER: { |
+ uint32 int_value; |
+ if (GetRegistryPolicyInteger(name, &int_value)) { |
+ result->SetInteger(current->name, int_value); |
+ } |
+ break; |
+ } |
+ default: |
+ NOTREACHED(); |
+ } |
+ } |
+ return result; |
+} |
+ |
+bool ConfigurationPolicyProviderDelegateWin::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 ConfigurationPolicyProviderDelegateWin::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 ConfigurationPolicyProviderDelegateWin::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 ConfigurationPolicyProviderDelegateWin::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; |
+} |
+ |
+} // namespace policy |