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 "policy/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) != ERROR_SUCCESS) 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 RegKey policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); 93 // First try the global policy. 94 if (ReadRegistryStringValue(&policy_key, name, result)) 95 return true; 96 97 // Fall back on user-specific policy. 98 if (policy_key.Open(HKEY_CURRENT_USER, kRegistrySubKey, 99 KEY_READ) != ERROR_SUCCESS) 100 return false; 101 return ReadRegistryStringValue(&policy_key, name, result); 102 } 103 104 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyStringList( 105 const string16& key, ListValue* result) const { 106 string16 path = string16(kRegistrySubKey); 107 path += ASCIIToUTF16("\\") + key; 108 RegKey policy_key; 109 if (policy_key.Open(HKEY_LOCAL_MACHINE, path.c_str(), KEY_READ) != 110 ERROR_SUCCESS) { 111 // Fall back on user-specific policy. 112 if (policy_key.Open(HKEY_CURRENT_USER, path.c_str(), KEY_READ) != 113 ERROR_SUCCESS) 114 return false; 115 } 116 string16 policy_string; 117 int index = 0; 118 while (ReadRegistryStringValue(&policy_key, base::IntToString16(++index), 119 &policy_string)) { 120 result->Append(Value::CreateStringValue(policy_string)); 121 } 122 return true; 123 } 124 125 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyBoolean( 126 const string16& value_name, bool* result) const { 127 uint32 local_result = 0; 128 bool ret = GetRegistryPolicyInteger(value_name, &local_result); 129 if (ret) 130 *result = local_result != 0; 131 return ret; 132 } 133 134 bool ConfigurationPolicyProviderDelegateWin::GetRegistryPolicyInteger( 135 const string16& value_name, uint32* result) const { 136 DWORD value = 0; 137 RegKey policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); 138 if (policy_key.ReadValueDW(value_name.c_str(), &value) == ERROR_SUCCESS) { 139 *result = value; 140 return true; 141 } 142 143 if (policy_key.Open(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ) == 144 ERROR_SUCCESS) { 145 if (policy_key.ReadValueDW(value_name.c_str(), &value) == ERROR_SUCCESS) { 146 *result = value; 147 return true; 148 } 149 } 150 return false; 151 } 152 153 } // namespace policy 154