OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 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/win/registry.h" | 8 #include "base/win/registry.h" |
9 #include "chrome/installer/util/logging_installer.h" | 9 #include "chrome/installer/util/logging_installer.h" |
10 | 10 |
(...skipping 25 matching lines...) Expand all Loading... |
36 key_path_(key_path), | 36 key_path_(key_path), |
37 value_name_(value_name), | 37 value_name_(value_name), |
38 value_data_dword_(value_data), | 38 value_data_dword_(value_data), |
39 overwrite_(overwrite), | 39 overwrite_(overwrite), |
40 status_(SET_VALUE), | 40 status_(SET_VALUE), |
41 is_str_type_(false), | 41 is_str_type_(false), |
42 previous_value_dword_(0) { | 42 previous_value_dword_(0) { |
43 } | 43 } |
44 | 44 |
45 bool SetRegValueWorkItem::Do() { | 45 bool SetRegValueWorkItem::Do() { |
46 bool success = true; | 46 LONG result = ERROR_SUCCESS; |
47 | 47 base::win::RegKey key; |
48 if (status_ != SET_VALUE) { | 48 if (status_ != SET_VALUE) { |
49 // we already did something. | 49 // we already did something. |
50 LOG(ERROR) << "multiple calls to Do()"; | 50 LOG(ERROR) << "multiple calls to Do()"; |
51 success = false; | 51 result = ERROR_CANTWRITE; |
| 52 } else { |
| 53 result = key.Open(predefined_root_, key_path_.c_str(), |
| 54 KEY_READ | KEY_SET_VALUE); |
| 55 if (result != ERROR_SUCCESS) { |
| 56 LOG(ERROR) << "can not open " << key_path_ << " error: " << result; |
| 57 status_ = VALUE_UNCHANGED; |
| 58 } |
52 } | 59 } |
53 | 60 |
54 base::win::RegKey key; | 61 if (result == ERROR_SUCCESS) { |
55 if (success && !key.Open(predefined_root_, key_path_.c_str(), | |
56 KEY_READ | KEY_SET_VALUE)) { | |
57 LOG(ERROR) << "can not open " << key_path_; | |
58 status_ = VALUE_UNCHANGED; | |
59 success = false; | |
60 } | |
61 | |
62 if (success) { | |
63 if (key.ValueExists(value_name_.c_str())) { | 62 if (key.ValueExists(value_name_.c_str())) { |
64 if (overwrite_) { | 63 if (overwrite_) { |
65 // Read previous value for rollback and write new value | 64 // Read previous value for rollback and write new value |
66 if (is_str_type_) { | 65 if (is_str_type_) { |
67 std::wstring data; | 66 key.ReadValue(value_name_.c_str(), &previous_value_str_); |
68 if (key.ReadValue(value_name_.c_str(), &data)) { | 67 result = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); |
69 previous_value_str_.assign(data); | 68 } else { |
| 69 key.ReadValueDW(value_name_.c_str(), &previous_value_dword_); |
| 70 result = key.WriteValue(value_name_.c_str(), value_data_dword_); |
| 71 } |
| 72 if (result == ERROR_SUCCESS) { |
| 73 VLOG(1) << "overwritten value for " << value_name_; |
| 74 status_ = VALUE_OVERWRITTEN; |
| 75 } else { |
| 76 LOG(ERROR) << "failed to overwrite value for " << value_name_; |
| 77 status_ = VALUE_UNCHANGED; |
70 } | 78 } |
71 success = key.WriteValue(value_name_.c_str(), | |
72 value_data_str_.c_str()); | |
73 } else { | |
74 DWORD data; | |
75 if (key.ReadValueDW(value_name_.c_str(), &data)) { | |
76 previous_value_dword_ = data; | |
77 } | |
78 success = key.WriteValue(value_name_.c_str(), value_data_dword_); | |
79 } | |
80 if (success) { | |
81 VLOG(1) << "overwritten value for " << value_name_; | |
82 status_ = VALUE_OVERWRITTEN; | |
83 } else { | |
84 LOG(ERROR) << "failed to overwrite value for " << value_name_; | |
85 status_ = VALUE_UNCHANGED; | |
86 } | |
87 } else { | 79 } else { |
| 80 // value exists and cannot be overwriten |
88 VLOG(1) << value_name_ << " exists. not changed "; | 81 VLOG(1) << value_name_ << " exists. not changed "; |
89 status_ = VALUE_UNCHANGED; | 82 status_ = VALUE_UNCHANGED; |
90 } | 83 } |
91 } else { | 84 } else { |
| 85 // Value does not exist, simply write a new value |
92 if (is_str_type_) { | 86 if (is_str_type_) { |
93 success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); | 87 result = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); |
94 } else { | 88 } else { |
95 success = key.WriteValue(value_name_.c_str(), value_data_dword_); | 89 result = key.WriteValue(value_name_.c_str(), value_data_dword_); |
96 } | 90 } |
97 if (success) { | 91 if (result == ERROR_SUCCESS) { |
98 VLOG(1) << "created value for " << value_name_; | 92 VLOG(1) << "created value for " << value_name_; |
99 status_ = NEW_VALUE_CREATED; | 93 status_ = NEW_VALUE_CREATED; |
100 } else { | 94 } else { |
101 LOG(ERROR) << "failed to create value for " << value_name_; | 95 LOG(ERROR) << "failed to create value for " << value_name_ |
| 96 << " error: " << result; |
102 status_ = VALUE_UNCHANGED; | 97 status_ = VALUE_UNCHANGED; |
103 } | 98 } |
104 } | 99 } |
105 } | 100 } |
106 | 101 |
107 LOG_IF(ERROR, !success && !log_message_.empty()) << log_message_; | |
108 | |
109 if (ignore_failure_) { | 102 if (ignore_failure_) { |
110 success = true; | 103 result = ERROR_SUCCESS; |
111 } | 104 } |
112 | 105 |
113 return success; | 106 return result == ERROR_SUCCESS; |
114 } | 107 } |
115 | 108 |
116 void SetRegValueWorkItem::Rollback() { | 109 void SetRegValueWorkItem::Rollback() { |
117 if (!ignore_failure_) { | 110 if (ignore_failure_) |
118 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK) | 111 return; |
119 return; | |
120 | 112 |
121 if (status_ == VALUE_UNCHANGED) { | 113 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK) |
122 status_ = VALUE_ROLL_BACK; | 114 return; |
123 VLOG(1) << "rollback: setting unchanged, nothing to do"; | |
124 return; | |
125 } | |
126 | 115 |
127 base::win::RegKey key; | 116 if (status_ == VALUE_UNCHANGED) { |
128 if (!key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE)) { | |
129 status_ = VALUE_ROLL_BACK; | |
130 VLOG(1) << "rollback: can not open " << key_path_; | |
131 return; | |
132 } | |
133 | |
134 std::wstring result_str(L" failed"); | |
135 if (status_ == NEW_VALUE_CREATED) { | |
136 if (key.DeleteValue(value_name_.c_str())) | |
137 result_str.assign(L" succeeded"); | |
138 VLOG(1) << "rollback: deleting " << value_name_ << result_str; | |
139 } else if (status_ == VALUE_OVERWRITTEN) { | |
140 // try restore the previous value | |
141 bool success = true; | |
142 if (is_str_type_) { | |
143 success = key.WriteValue(value_name_.c_str(), | |
144 previous_value_str_.c_str()); | |
145 } else { | |
146 success = key.WriteValue(value_name_.c_str(), previous_value_dword_); | |
147 } | |
148 if (success) | |
149 result_str.assign(L" succeeded"); | |
150 VLOG(1) << "rollback: restoring " << value_name_ << result_str; | |
151 } else { | |
152 NOTREACHED(); | |
153 } | |
154 | |
155 status_ = VALUE_ROLL_BACK; | 117 status_ = VALUE_ROLL_BACK; |
| 118 VLOG(1) << "rollback: setting unchanged, nothing to do"; |
156 return; | 119 return; |
157 } | 120 } |
| 121 |
| 122 base::win::RegKey key; |
| 123 LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE); |
| 124 if (result != ERROR_SUCCESS) { |
| 125 status_ = VALUE_ROLL_BACK; |
| 126 VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result; |
| 127 return; |
| 128 } |
| 129 |
| 130 if (status_ == NEW_VALUE_CREATED) { |
| 131 result = key.DeleteValue(value_name_.c_str()); |
| 132 VLOG(1) << "rollback: deleting " << value_name_ << " error: " << result; |
| 133 } else if (status_ == VALUE_OVERWRITTEN) { |
| 134 // try restore the previous value |
| 135 if (is_str_type_) { |
| 136 result = key.WriteValue(value_name_.c_str(), previous_value_str_.c_str()); |
| 137 } else { |
| 138 result = key.WriteValue(value_name_.c_str(), previous_value_dword_); |
| 139 } |
| 140 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result; |
| 141 } else { |
| 142 NOTREACHED(); |
| 143 } |
| 144 |
| 145 status_ = VALUE_ROLL_BACK; |
158 } | 146 } |
OLD | NEW |