• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ReadRegistryStringValue(RegKey * key,const string16 & name,string16 * result)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 
ConfigurationPolicyProviderDelegateWin(const ConfigurationPolicyProvider::PolicyDefinitionList * policy_definition_list)42 ConfigurationPolicyProviderDelegateWin::ConfigurationPolicyProviderDelegateWin(
43     const ConfigurationPolicyProvider::PolicyDefinitionList*
44         policy_definition_list)
45     : policy_definition_list_(policy_definition_list) {
46 }
47 
Load()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 
GetRegistryPolicyString(const string16 & name,string16 * result) const90 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 
GetRegistryPolicyStringList(const string16 & key,ListValue * result) const104 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 
GetRegistryPolicyBoolean(const string16 & value_name,bool * result) const125 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 
GetRegistryPolicyInteger(const string16 & value_name,uint32 * result) const134 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