OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/installer/util/set_reg_value_work_item.h" | 5 #include "chrome/installer/util/set_reg_value_work_item.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "base/win/registry.h" | 9 #include "base/win/registry.h" |
10 #include "chrome/installer/util/logging_installer.h" | 10 #include "chrome/installer/util/logging_installer.h" |
11 | 11 |
| 12 namespace { |
| 13 |
| 14 // Transforms |str_value| into the byte-by-byte representation of its underlying |
| 15 // string, stores the result in |binary_data|. |
| 16 void StringToBinaryData(const std::wstring& str_value, |
| 17 std::vector<uint8>* binary_data) { |
| 18 DCHECK(binary_data); |
| 19 const uint8* data = reinterpret_cast<const uint8*>(str_value.c_str()); |
| 20 binary_data->assign(data, data + (str_value.length() + 1) * sizeof(wchar_t)); |
| 21 } |
| 22 |
| 23 // Transforms |binary_data| into its wstring representation (assuming |
| 24 // |binary_data| is a sequence of wchar_t's). |
| 25 void BinaryDataToString(const std::vector<uint8>& binary_data, |
| 26 std::wstring* str_value) { |
| 27 DCHECK(str_value); |
| 28 if (binary_data.size() < sizeof(wchar_t)) { |
| 29 str_value->clear(); |
| 30 return; |
| 31 } |
| 32 |
| 33 str_value->assign(reinterpret_cast<const wchar_t*>(&binary_data[0]), |
| 34 binary_data.size() / sizeof(wchar_t)); |
| 35 |
| 36 // Trim off a trailing string terminator, if present. |
| 37 if (!str_value->empty()) { |
| 38 auto iter = str_value->end(); |
| 39 if (*--iter == L'\0') |
| 40 str_value->erase(iter); |
| 41 } |
| 42 } |
| 43 |
| 44 } // namespace |
| 45 |
12 SetRegValueWorkItem::~SetRegValueWorkItem() { | 46 SetRegValueWorkItem::~SetRegValueWorkItem() { |
13 } | 47 } |
14 | 48 |
15 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, | 49 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, |
16 const std::wstring& key_path, | 50 const std::wstring& key_path, |
17 REGSAM wow64_access, | 51 REGSAM wow64_access, |
18 const std::wstring& value_name, | 52 const std::wstring& value_name, |
19 const std::wstring& value_data, | 53 const std::wstring& value_data, |
20 bool overwrite) | 54 bool overwrite) |
21 : predefined_root_(predefined_root), | 55 : predefined_root_(predefined_root), |
22 key_path_(key_path), | 56 key_path_(key_path), |
23 value_name_(value_name), | 57 value_name_(value_name), |
24 overwrite_(overwrite), | 58 overwrite_(overwrite), |
25 wow64_access_(wow64_access), | 59 wow64_access_(wow64_access), |
26 status_(SET_VALUE), | 60 status_(SET_VALUE), |
27 type_(REG_SZ), | 61 type_(REG_SZ), |
28 previous_type_(0) { | 62 previous_type_(0) { |
29 DCHECK(wow64_access == 0 || | 63 DCHECK(wow64_access == 0 || |
30 wow64_access == KEY_WOW64_32KEY || | 64 wow64_access == KEY_WOW64_32KEY || |
31 wow64_access == KEY_WOW64_64KEY); | 65 wow64_access == KEY_WOW64_64KEY); |
32 const uint8* data = reinterpret_cast<const uint8*>(value_data.c_str()); | 66 StringToBinaryData(value_data, &value_); |
33 value_.assign(data, data + (value_data.length() + 1) * sizeof(wchar_t)); | |
34 } | 67 } |
35 | 68 |
36 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, | 69 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, |
37 const std::wstring& key_path, | 70 const std::wstring& key_path, |
38 REGSAM wow64_access, | 71 REGSAM wow64_access, |
39 const std::wstring& value_name, | 72 const std::wstring& value_name, |
40 DWORD value_data, | 73 DWORD value_data, |
41 bool overwrite) | 74 bool overwrite) |
42 : predefined_root_(predefined_root), | 75 : predefined_root_(predefined_root), |
43 key_path_(key_path), | 76 key_path_(key_path), |
(...skipping 24 matching lines...) Expand all Loading... |
68 status_(SET_VALUE), | 101 status_(SET_VALUE), |
69 type_(REG_QWORD), | 102 type_(REG_QWORD), |
70 previous_type_(0) { | 103 previous_type_(0) { |
71 DCHECK(wow64_access == 0 || | 104 DCHECK(wow64_access == 0 || |
72 wow64_access == KEY_WOW64_32KEY || | 105 wow64_access == KEY_WOW64_32KEY || |
73 wow64_access == KEY_WOW64_64KEY); | 106 wow64_access == KEY_WOW64_64KEY); |
74 const uint8* data = reinterpret_cast<const uint8*>(&value_data); | 107 const uint8* data = reinterpret_cast<const uint8*>(&value_data); |
75 value_.assign(data, data + sizeof(value_data)); | 108 value_.assign(data, data + sizeof(value_data)); |
76 } | 109 } |
77 | 110 |
| 111 SetRegValueWorkItem::SetRegValueWorkItem( |
| 112 HKEY predefined_root, |
| 113 const std::wstring& key_path, |
| 114 REGSAM wow64_access, |
| 115 const std::wstring& value_name, |
| 116 const GetValueFromExistingCallback& get_value_callback) |
| 117 : predefined_root_(predefined_root), |
| 118 key_path_(key_path), |
| 119 value_name_(value_name), |
| 120 get_value_callback_(get_value_callback), |
| 121 overwrite_(true), |
| 122 wow64_access_(wow64_access), |
| 123 status_(SET_VALUE), |
| 124 type_(REG_SZ), |
| 125 previous_type_(0) { |
| 126 DCHECK(wow64_access == 0 || |
| 127 wow64_access == KEY_WOW64_32KEY || |
| 128 wow64_access == KEY_WOW64_64KEY); |
| 129 // Nothing to do, |get_value_callback| will fill |value_| later. |
| 130 } |
| 131 |
78 bool SetRegValueWorkItem::Do() { | 132 bool SetRegValueWorkItem::Do() { |
79 LONG result = ERROR_SUCCESS; | 133 LONG result = ERROR_SUCCESS; |
80 base::win::RegKey key; | 134 base::win::RegKey key; |
81 if (status_ != SET_VALUE) { | 135 if (status_ != SET_VALUE) { |
82 // we already did something. | 136 // we already did something. |
83 VLOG(1) << "multiple calls to Do()"; | 137 VLOG(1) << "multiple calls to Do()"; |
84 result = ERROR_CANTWRITE; | 138 result = ERROR_CANTWRITE; |
85 return ignore_failure_; | 139 return ignore_failure_; |
86 } | 140 } |
87 | 141 |
(...skipping 23 matching lines...) Expand all Loading... |
111 previous_value_.resize(size); | 165 previous_value_.resize(size); |
112 result = key.ReadValue(value_name_.c_str(), &previous_value_[0], &size, | 166 result = key.ReadValue(value_name_.c_str(), &previous_value_[0], &size, |
113 &previous_type_); | 167 &previous_type_); |
114 if (result != ERROR_SUCCESS) { | 168 if (result != ERROR_SUCCESS) { |
115 previous_value_.clear(); | 169 previous_value_.clear(); |
116 VLOG(1) << "Failed to save original value. Error: " << result; | 170 VLOG(1) << "Failed to save original value. Error: " << result; |
117 } | 171 } |
118 } | 172 } |
119 } | 173 } |
120 | 174 |
| 175 if (!get_value_callback_.is_null()) { |
| 176 // Although this could be made more generic, for now this assumes the |
| 177 // |type_| of |value_| is REG_SZ. |
| 178 DCHECK_EQ(static_cast<DWORD>(REG_SZ), type_); |
| 179 |
| 180 // Fill |previous_value_str| with the wstring representation of the binary |
| 181 // data in |previous_value_| as long as it's of type REG_SZ (leave it empty |
| 182 // otherwise). |
| 183 std::wstring previous_value_str; |
| 184 if (previous_type_ == REG_SZ) |
| 185 BinaryDataToString(previous_value_, &previous_value_str); |
| 186 |
| 187 StringToBinaryData(get_value_callback_.Run(previous_value_str), &value_); |
| 188 } |
| 189 |
121 result = key.WriteValue(value_name_.c_str(), &value_[0], | 190 result = key.WriteValue(value_name_.c_str(), &value_[0], |
122 static_cast<DWORD>(value_.size()), type_); | 191 static_cast<DWORD>(value_.size()), type_); |
123 if (result != ERROR_SUCCESS) { | 192 if (result != ERROR_SUCCESS) { |
124 VLOG(1) << "Failed to write value " << key_path_ << " error: " << result; | 193 VLOG(1) << "Failed to write value " << key_path_ << " error: " << result; |
125 return ignore_failure_; | 194 return ignore_failure_; |
126 } | 195 } |
127 | 196 |
128 status_ = previous_type_ ? VALUE_OVERWRITTEN : NEW_VALUE_CREATED; | 197 status_ = previous_type_ ? VALUE_OVERWRITTEN : NEW_VALUE_CREATED; |
129 return true; | 198 return true; |
130 } | 199 } |
(...skipping 28 matching lines...) Expand all Loading... |
159 result = key.WriteValue(value_name_.c_str(), previous_value, | 228 result = key.WriteValue(value_name_.c_str(), previous_value, |
160 static_cast<DWORD>(previous_value_.size()), | 229 static_cast<DWORD>(previous_value_.size()), |
161 previous_type_); | 230 previous_type_); |
162 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result; | 231 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result; |
163 } else { | 232 } else { |
164 NOTREACHED(); | 233 NOTREACHED(); |
165 } | 234 } |
166 | 235 |
167 status_ = VALUE_ROLL_BACK; | 236 status_ = VALUE_ROLL_BACK; |
168 } | 237 } |
OLD | NEW |