OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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. |
| 4 |
| 5 #include "chrome/browser/policy/configuration_policy_provider_delegate_win.h" |
| 6 |
| 7 #include "base/string_number_conversions.h" |
| 8 #include "base/utf_string_conversions.h" |
| 9 #include "base/win/registry.h" |
| 10 #include "chrome/common/policy_constants.h" |
| 11 |
| 12 using base::win::RegKey; |
| 13 |
| 14 namespace { |
| 15 |
| 16 bool ReadRegistryStringValue(RegKey* key, const string16& name, |
| 17 string16* result) { |
| 18 DWORD value_size = 0; |
| 19 DWORD key_type = 0; |
| 20 scoped_array<uint8> buffer; |
| 21 |
| 22 if (!key->ReadValue(name.c_str(), 0, &value_size, &key_type)) |
| 23 return false; |
| 24 if (key_type != REG_SZ) |
| 25 return false; |
| 26 |
| 27 // According to the Microsoft documentation, the string |
| 28 // buffer may not be explicitly 0-terminated. Allocate a |
| 29 // slightly larger buffer and pre-fill to zeros to guarantee |
| 30 // the 0-termination. |
| 31 buffer.reset(new uint8[value_size + 2]); |
| 32 memset(buffer.get(), 0, value_size + 2); |
| 33 key->ReadValue(name.c_str(), buffer.get(), &value_size, NULL); |
| 34 result->assign(reinterpret_cast<const wchar_t*>(buffer.get())); |
| 35 return true; |
| 36 } |
| 37 |
| 38 } // namespace |
| 39 |
| 40 namespace policy { |
| 41 |
| 42 ConfigurationPolicyProviderDelegateWin::ConfigurationPolicyProviderDelegateWin( |
| 43 const ConfigurationPolicyProvider::PolicyDefinitionList* |
| 44 policy_definition_list) |
| 45 : policy_definition_list_(policy_definition_list) { |
| 46 } |
| 47 |
| 48 DictionaryValue* ConfigurationPolicyProviderDelegateWin::Load() { |
| 49 DictionaryValue* result = new DictionaryValue(); |
| 50 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; |
| 51 for (current = policy_definition_list_->begin; |
| 52 current != policy_definition_list_->end; |
| 53 ++current) { |
| 54 const string16 name(ASCIIToUTF16(current->name)); |
| 55 switch (current->value_type) { |
| 56 case Value::TYPE_STRING: { |
| 57 string16 string_value; |
| 58 if (GetRegistryPolicyString(name, &string_value)) { |
| 59 result->SetString(current->name, string_value); |
| 60 } |
| 61 break; |
| 62 } |
| 63 case Value::TYPE_LIST: { |
| 64 scoped_ptr<ListValue> list_value(new ListValue); |
| 65 if (GetRegistryPolicyStringList(name, list_value.get())) |
| 66 result->Set(current->name, list_value.release()); |
| 67 break; |
| 68 } |
| 69 case Value::TYPE_BOOLEAN: { |
| 70 bool bool_value; |
| 71 if (GetRegistryPolicyBoolean(name, &bool_value)) { |
| 72 result->SetBoolean(current->name, bool_value); |
| 73 } |
| 74 break; |
| 75 } |
| 76 case Value::TYPE_INTEGER: { |
| 77 uint32 int_value; |
| 78 if (GetRegistryPolicyInteger(name, &int_value)) { |
| 79 result->SetInteger(current->name, int_value); |
| 80 } |
| 81 break; |
| 82 } |
| 83 default: |
| 84 NOTREACHED(); |
| 85 } |
| 86 } |
| 87 return result; |
| 88 } |
| 89 |
| 90 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyString( |
| 91 const string16& name, string16* result) const { |
| 92 string16 path = string16(kRegistrySubKey); |
| 93 RegKey policy_key; |
| 94 // First try the global policy. |
| 95 if (policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) { |
| 96 if (ReadRegistryStringValue(&policy_key, name, result)) |
| 97 return true; |
| 98 policy_key.Close(); |
| 99 } |
| 100 // Fall back on user-specific policy. |
| 101 if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ)) |
| 102 return false; |
| 103 return ReadRegistryStringValue(&policy_key, name, result); |
| 104 } |
| 105 |
| 106 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyStringList( |
| 107 const string16& key, ListValue* result) const { |
| 108 string16 path = string16(kRegistrySubKey); |
| 109 path += ASCIIToUTF16("\\") + key; |
| 110 RegKey policy_key; |
| 111 if (!policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ)) { |
| 112 policy_key.Close(); |
| 113 // Fall back on user-specific policy. |
| 114 if (!policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ)) |
| 115 return false; |
| 116 } |
| 117 string16 policy_string; |
| 118 int index = 0; |
| 119 while (ReadRegistryStringValue(&policy_key, base::IntToString16(++index), |
| 120 &policy_string)) { |
| 121 result->Append(Value::CreateStringValue(policy_string)); |
| 122 } |
| 123 return true; |
| 124 } |
| 125 |
| 126 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyBoolean( |
| 127 const string16& value_name, bool* result) const { |
| 128 DWORD value; |
| 129 RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); |
| 130 if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
| 131 *result = value != 0; |
| 132 return true; |
| 133 } |
| 134 |
| 135 RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ); |
| 136 if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
| 137 *result = value != 0; |
| 138 return true; |
| 139 } |
| 140 return false; |
| 141 } |
| 142 |
| 143 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyInteger( |
| 144 const string16& value_name, uint32* result) const { |
| 145 DWORD value; |
| 146 RegKey hkcu_policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); |
| 147 if (hkcu_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
| 148 *result = value; |
| 149 return true; |
| 150 } |
| 151 |
| 152 RegKey hklm_policy_key(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ); |
| 153 if (hklm_policy_key.ReadValueDW(value_name.c_str(), &value)) { |
| 154 *result = value; |
| 155 return true; |
| 156 } |
| 157 return false; |
| 158 } |
| 159 |
| 160 } // namespace policy |
OLD | NEW |