Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: chrome/installer/util/set_reg_value_work_item.cc

Issue 6090006: Regkey functions return error code instead of bool (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/string_util.h"
8 #include "base/win/registry.h" 9 #include "base/win/registry.h"
9 #include "chrome/installer/util/logging_installer.h" 10 #include "chrome/installer/util/logging_installer.h"
10 11
11 SetRegValueWorkItem::~SetRegValueWorkItem() { 12 SetRegValueWorkItem::~SetRegValueWorkItem() {
12 } 13 }
13 14
14 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, 15 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
15 const std::wstring& key_path, 16 const std::wstring& key_path,
16 const std::wstring& value_name, 17 const std::wstring& value_name,
17 const std::wstring& value_data, 18 const std::wstring& value_data,
18 bool overwrite) 19 bool overwrite)
19 : predefined_root_(predefined_root), 20 : predefined_root_(predefined_root),
20 key_path_(key_path), 21 key_path_(key_path),
21 value_name_(value_name), 22 value_name_(value_name),
22 value_data_str_(value_data),
23 value_data_dword_(0),
24 value_data_qword_(0),
25 overwrite_(overwrite), 23 overwrite_(overwrite),
26 status_(SET_VALUE), 24 status_(SET_VALUE),
27 type_(REG_SZ), 25 type_(REG_SZ) {
28 previous_value_dword_(0), 26 const char* data = reinterpret_cast<const char*>(value_data.c_str());
29 previous_value_qword_(0) { 27 value_.assign(data, value_data.length() * sizeof(wchar_t));
grt (UTC plus 2) 2011/01/14 15:53:43 You must use (value_data.length() + 1) * sizeof(wc
amit 2011/01/15 01:28:11 Done.
30 } 28 }
31 29
32 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, 30 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
33 const std::wstring& key_path, 31 const std::wstring& key_path,
34 const std::wstring& value_name, 32 const std::wstring& value_name,
35 DWORD value_data, 33 DWORD value_data,
36 bool overwrite) 34 bool overwrite)
37 : predefined_root_(predefined_root), 35 : predefined_root_(predefined_root),
38 key_path_(key_path), 36 key_path_(key_path),
39 value_name_(value_name), 37 value_name_(value_name),
40 value_data_dword_(value_data),
41 value_data_qword_(0),
42 overwrite_(overwrite), 38 overwrite_(overwrite),
43 status_(SET_VALUE), 39 status_(SET_VALUE),
44 type_(REG_DWORD), 40 type_(REG_DWORD) {
45 previous_value_dword_(0), 41 const char* data = reinterpret_cast<const char*>(&value_data);
46 previous_value_qword_(0) { 42 value_.assign(data, sizeof(value_data));
47 } 43 }
48 44
49 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, 45 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
50 const std::wstring& key_path, 46 const std::wstring& key_path,
51 const std::wstring& value_name, 47 const std::wstring& value_name,
52 int64 value_data, 48 int64 value_data,
53 bool overwrite) 49 bool overwrite)
54 : predefined_root_(predefined_root), 50 : predefined_root_(predefined_root),
55 key_path_(key_path), 51 key_path_(key_path),
56 value_name_(value_name), 52 value_name_(value_name),
57 value_data_dword_(0),
58 value_data_qword_(value_data),
59 overwrite_(overwrite), 53 overwrite_(overwrite),
60 status_(SET_VALUE), 54 status_(SET_VALUE),
61 type_(REG_QWORD), 55 type_(REG_QWORD) {
62 previous_value_dword_(0), 56 const char* data = reinterpret_cast<const char*>(&value_data);
63 previous_value_qword_(0) { 57 value_.assign(data, sizeof(value_data));
64 } 58 }
65 59
66 bool SetRegValueWorkItem::Do() { 60 bool SetRegValueWorkItem::Do() {
67 bool success = true; 61 LONG result = ERROR_SUCCESS;
68 62 base::win::RegKey key;
69 if (status_ != SET_VALUE) { 63 if (status_ != SET_VALUE) {
70 // we already did something. 64 // we already did something.
71 LOG(ERROR) << "multiple calls to Do()"; 65 VLOG(1) << "multiple calls to Do()";
72 success = false; 66 result = ERROR_CANTWRITE;
67 return ignore_failure_;
68 }
69
70 status_ = VALUE_UNCHANGED;
71 result = key.Open(predefined_root_, key_path_.c_str(),
72 KEY_READ | KEY_SET_VALUE);
73 if (result != ERROR_SUCCESS) {
74 VLOG(1) << "can not open " << key_path_ << " error: " << result;
75 return ignore_failure_;
76 }
77
78 DWORD type = 0;
79 DWORD size = 0;
80 result = key.ReadValue(value_name_.c_str(), NULL, &size, &type);
81 // If the value exists but we don't want to overwrite then there's
82 // nothing mroe to do.
83 if (!overwrite_ && result != ERROR_FILE_NOT_FOUND) {
grt (UTC plus 2) 2011/01/14 15:53:43 nit: make the order of the tests and the order of
amit 2011/01/15 01:28:11 Done.
84 return ignore_failure_;
85 }
86
87 // If there's something to be saved, save it.
88 if (result == ERROR_MORE_DATA) {
grt (UTC plus 2) 2011/01/14 15:53:43 Same comment as before: MSDN leads me to believe t
amit 2011/01/15 01:28:11 Done.
89 result = key.ReadValue(value_name_.c_str(),
90 WriteInto(&previous_value_, size), &size,
91 &previous_type_);
92 VLOG_IF(1, result != ERROR_SUCCESS) << "Failed to save original value. "
93 "Error: " << result;
94 }
95
96 result = key.WriteValue(value_name_.c_str(), value_.c_str(),
grt (UTC plus 2) 2011/01/14 15:53:43 If you stick with std::string, use data() rather t
amit 2011/01/15 01:28:11 Done.
97 static_cast<DWORD>(value_.size()), type_);
98 if (result != ERROR_SUCCESS) {
99 VLOG(1) << "Failed to write value " << key_path_ << " error: " << result;
100 return ignore_failure_;
101 }
102
103 status_ = overwrite_ ? VALUE_OVERWRITTEN : NEW_VALUE_CREATED;
104 return true;
105 }
106
107 void SetRegValueWorkItem::Rollback() {
108 if (ignore_failure_)
109 return;
110
111 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
112 return;
113
114 status_ = VALUE_ROLL_BACK;
grt (UTC plus 2) 2011/01/14 15:53:43 This is wrong.
amit 2011/01/15 01:28:11 Good catch, removed.
115 if (status_ == VALUE_UNCHANGED) {
116 VLOG(1) << "rollback: setting unchanged, nothing to do";
117 return;
73 } 118 }
74 119
75 base::win::RegKey key; 120 base::win::RegKey key;
76 if (success && !key.Open(predefined_root_, key_path_.c_str(), 121 LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE);
77 KEY_READ | KEY_SET_VALUE)) { 122 if (result != ERROR_SUCCESS) {
78 LOG(ERROR) << "can not open " << key_path_; 123 VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result;
79 status_ = VALUE_UNCHANGED; 124 return;
80 success = false;
81 } 125 }
82 126
83 if (success) { 127 if (status_ == NEW_VALUE_CREATED) {
84 if (key.ValueExists(value_name_.c_str())) { 128 result = key.DeleteValue(value_name_.c_str());
85 if (overwrite_) { 129 VLOG(1) << "rollback: deleting " << value_name_ << " error: " << result;
86 // Read previous value for rollback and write new value 130 } else if (status_ == VALUE_OVERWRITTEN) {
87 if (type_ == REG_SZ) { 131 result = key.WriteValue(value_name_.c_str(), previous_value_.c_str(),
grt (UTC plus 2) 2011/01/14 15:53:43 If you stick with std::string, use data() rather t
88 std::wstring data; 132 static_cast<DWORD>(previous_value_.size()),
89 if (key.ReadValue(value_name_.c_str(), &data)) { 133 previous_type_);
90 previous_value_str_.assign(data); 134 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result;
91 } 135 } else {
92 success = key.WriteValue(value_name_.c_str(), 136 NOTREACHED();
93 value_data_str_.c_str());
94 } else if (type_ == REG_DWORD) {
95 DWORD data;
96 if (key.ReadValueDW(value_name_.c_str(), &data)) {
97 previous_value_dword_ = data;
98 }
99 success = key.WriteValue(value_name_.c_str(), value_data_dword_);
100 } else if (type_ == REG_QWORD) {
101 int64 data;
102 DWORD data_size = sizeof(data);
103 DWORD data_type = NULL;
104
105 if (key.ReadValue(value_name_.c_str(), &data, &data_size,
106 &data_type)) {
107 previous_value_qword_ = data;
108 }
109 success = key.WriteValue(value_name_.c_str(),
110 &value_data_qword_,
111 sizeof(value_data_qword_),
112 REG_QWORD);
113 }
114 if (success) {
115 VLOG(1) << "overwritten value for " << value_name_;
116 status_ = VALUE_OVERWRITTEN;
117 } else {
118 LOG(ERROR) << "failed to overwrite value for " << value_name_;
119 status_ = VALUE_UNCHANGED;
120 }
121 } else {
122 VLOG(1) << value_name_ << " exists. not changed ";
123 status_ = VALUE_UNCHANGED;
124 }
125 } else {
126 if (type_ == REG_SZ) {
127 success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str());
128 } else if (type_ == REG_DWORD) {
129 success = key.WriteValue(value_name_.c_str(), value_data_dword_);
130 } else if (type_ == REG_QWORD) {
131 success = key.WriteValue(value_name_.c_str(),
132 &value_data_qword_,
133 sizeof(value_data_qword_),
134 REG_QWORD);
135 } else {
136 NOTREACHED() << "Unsupported value type.";
137 }
138 if (success) {
139 VLOG(1) << "created value for " << value_name_;
140 status_ = NEW_VALUE_CREATED;
141 } else {
142 LOG(ERROR) << "failed to create value for " << value_name_;
143 status_ = VALUE_UNCHANGED;
144 }
145 }
146 }
147
148 LOG_IF(ERROR, !success && !log_message_.empty()) << log_message_;
149
150 if (ignore_failure_) {
151 success = true;
152 }
153
154 return success;
155 }
156
157 void SetRegValueWorkItem::Rollback() {
158 if (!ignore_failure_) {
159 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
160 return;
161
162 if (status_ == VALUE_UNCHANGED) {
163 status_ = VALUE_ROLL_BACK;
164 VLOG(1) << "rollback: setting unchanged, nothing to do";
165 return;
166 }
167
168 base::win::RegKey key;
169 if (!key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE)) {
170 status_ = VALUE_ROLL_BACK;
171 VLOG(1) << "rollback: can not open " << key_path_;
172 return;
173 }
174
175 std::wstring result_str(L" failed");
176 if (status_ == NEW_VALUE_CREATED) {
177 if (key.DeleteValue(value_name_.c_str()))
178 result_str.assign(L" succeeded");
179 VLOG(1) << "rollback: deleting " << value_name_ << result_str;
180 } else if (status_ == VALUE_OVERWRITTEN) {
181 // try restore the previous value
182 bool success = true;
183 if (type_ == REG_SZ) {
184 success = key.WriteValue(value_name_.c_str(),
185 previous_value_str_.c_str());
186 } else if (type_ == REG_DWORD) {
187 success = key.WriteValue(value_name_.c_str(), previous_value_dword_);
188 } else if (type_ == REG_QWORD) {
189 success = key.WriteValue(value_name_.c_str(),
190 &previous_value_qword_,
191 sizeof(previous_value_qword_),
192 REG_QWORD);
193 } else {
194 NOTREACHED();
195 }
196 if (success)
197 result_str.assign(L" succeeded");
198 VLOG(1) << "rollback: restoring " << value_name_ << result_str;
199
200 status_ = VALUE_ROLL_BACK;
201 return;
202 }
203 } 137 }
204 } 138 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698