| 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
|
|
|