Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / installer / util / set_reg_value_work_item.cc
blobb805a5d0af995071c30be984c291ac6576f22a6d
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
3 // found in the LICENSE file.
5 #include "chrome/installer/util/set_reg_value_work_item.h"
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "base/win/registry.h"
10 #include "chrome/installer/util/logging_installer.h"
12 SetRegValueWorkItem::~SetRegValueWorkItem() {
15 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
16 const std::wstring& key_path,
17 const std::wstring& value_name,
18 const std::wstring& value_data,
19 bool overwrite)
20 : predefined_root_(predefined_root),
21 key_path_(key_path),
22 value_name_(value_name),
23 overwrite_(overwrite),
24 status_(SET_VALUE),
25 type_(REG_SZ),
26 previous_type_(0) {
27 const uint8* data = reinterpret_cast<const uint8*>(value_data.c_str());
28 value_.assign(data, data + (value_data.length() + 1) * sizeof(wchar_t));
31 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
32 const std::wstring& key_path,
33 const std::wstring& value_name,
34 DWORD value_data,
35 bool overwrite)
36 : predefined_root_(predefined_root),
37 key_path_(key_path),
38 value_name_(value_name),
39 overwrite_(overwrite),
40 status_(SET_VALUE),
41 type_(REG_DWORD),
42 previous_type_(0) {
43 const uint8* data = reinterpret_cast<const uint8*>(&value_data);
44 value_.assign(data, data + sizeof(value_data));
47 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
48 const std::wstring& key_path,
49 const std::wstring& value_name,
50 int64 value_data,
51 bool overwrite)
52 : predefined_root_(predefined_root),
53 key_path_(key_path),
54 value_name_(value_name),
55 overwrite_(overwrite),
56 status_(SET_VALUE),
57 type_(REG_QWORD),
58 previous_type_(0) {
59 const uint8* data = reinterpret_cast<const uint8*>(&value_data);
60 value_.assign(data, data + sizeof(value_data));
63 bool SetRegValueWorkItem::Do() {
64 LONG result = ERROR_SUCCESS;
65 base::win::RegKey key;
66 if (status_ != SET_VALUE) {
67 // we already did something.
68 VLOG(1) << "multiple calls to Do()";
69 result = ERROR_CANTWRITE;
70 return ignore_failure_;
73 status_ = VALUE_UNCHANGED;
74 result = key.Open(predefined_root_, key_path_.c_str(),
75 KEY_READ | KEY_SET_VALUE);
76 if (result != ERROR_SUCCESS) {
77 VLOG(1) << "can not open " << key_path_ << " error: " << result;
78 return ignore_failure_;
81 DWORD type = 0;
82 DWORD size = 0;
83 result = key.ReadValue(value_name_.c_str(), NULL, &size, &type);
84 // If the value exists but we don't want to overwrite then there's
85 // nothing more to do.
86 if ((result != ERROR_FILE_NOT_FOUND) && !overwrite_) {
87 return true;
90 // If there's something to be saved, save it.
91 if (result == ERROR_SUCCESS) {
92 if (!size) {
93 previous_type_ = type;
94 } else {
95 previous_value_.resize(size);
96 result = key.ReadValue(value_name_.c_str(), &previous_value_[0], &size,
97 &previous_type_);
98 if (result != ERROR_SUCCESS) {
99 previous_value_.clear();
100 VLOG(1) << "Failed to save original value. Error: " << result;
105 result = key.WriteValue(value_name_.c_str(), &value_[0],
106 static_cast<DWORD>(value_.size()), type_);
107 if (result != ERROR_SUCCESS) {
108 VLOG(1) << "Failed to write value " << key_path_ << " error: " << result;
109 return ignore_failure_;
112 status_ = previous_type_ ? VALUE_OVERWRITTEN : NEW_VALUE_CREATED;
113 return true;
116 void SetRegValueWorkItem::Rollback() {
117 if (ignore_failure_)
118 return;
120 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
121 return;
123 if (status_ == VALUE_UNCHANGED) {
124 status_ = VALUE_ROLL_BACK;
125 VLOG(1) << "rollback: setting unchanged, nothing to do";
126 return;
129 base::win::RegKey key;
130 LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE);
131 if (result != ERROR_SUCCESS) {
132 VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result;
133 return;
136 if (status_ == NEW_VALUE_CREATED) {
137 result = key.DeleteValue(value_name_.c_str());
138 VLOG(1) << "rollback: deleting " << value_name_ << " error: " << result;
139 } else if (status_ == VALUE_OVERWRITTEN) {
140 const unsigned char* previous_value =
141 previous_value_.empty() ? NULL : &previous_value_[0];
142 result = key.WriteValue(value_name_.c_str(), previous_value,
143 static_cast<DWORD>(previous_value_.size()),
144 previous_type_);
145 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result;
146 } else {
147 NOTREACHED();
150 status_ = VALUE_ROLL_BACK;