1 // Copyright (c) 2012 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/delete_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 using base::win::RegKey
;
14 DeleteRegValueWorkItem::DeleteRegValueWorkItem(HKEY predefined_root
,
15 const std::wstring
& key_path
,
17 const std::wstring
& value_name
)
18 : predefined_root_(predefined_root
),
20 value_name_(value_name
),
21 wow64_access_(wow64_access
),
22 status_(DELETE_VALUE
),
24 DCHECK(wow64_access
== 0 ||
25 wow64_access
== KEY_WOW64_32KEY
||
26 wow64_access
== KEY_WOW64_64KEY
);
29 DeleteRegValueWorkItem::~DeleteRegValueWorkItem() {
32 bool DeleteRegValueWorkItem::Do() {
33 if (status_
!= DELETE_VALUE
) {
34 // we already did something.
35 LOG(ERROR
) << "multiple calls to Do()";
39 status_
= VALUE_UNCHANGED
;
44 LONG result
= key
.Open(predefined_root_
,
46 KEY_READ
| KEY_WRITE
| wow64_access_
);
47 if (result
== ERROR_SUCCESS
)
48 result
= key
.ReadValue(value_name_
.c_str(), NULL
, &size
, &type
);
50 if (result
== ERROR_FILE_NOT_FOUND
) {
51 LOG(INFO
) << "(delete value) Key: " << key_path_
<< " or Value: "
52 << value_name_
<< " does not exist.";
53 status_
= VALUE_NOT_FOUND
;
57 if (result
== ERROR_SUCCESS
) {
59 previous_type_
= type
;
61 previous_value_
.resize(size
);
62 result
= key
.ReadValue(value_name_
.c_str(), &previous_value_
[0], &size
,
64 if (result
!= ERROR_SUCCESS
) {
65 previous_value_
.erase();
66 VLOG(1) << "Failed to save original value. Error: " << result
;
71 result
= key
.DeleteValue(value_name_
.c_str());
72 if (result
!= ERROR_SUCCESS
) {
73 VLOG(1) << "Failed to delete value " << value_name_
<< " error: " << result
;
77 status_
= VALUE_DELETED
;
81 void DeleteRegValueWorkItem::Rollback() {
82 if (status_
== DELETE_VALUE
|| status_
== VALUE_ROLLED_BACK
)
84 if (status_
== VALUE_UNCHANGED
|| status_
== VALUE_NOT_FOUND
) {
85 status_
= VALUE_ROLLED_BACK
;
86 VLOG(1) << "rollback: setting unchanged, nothing to do";
90 // At this point only possible state is VALUE_DELETED.
92 LONG result
= key
.Open(predefined_root_
,
94 KEY_READ
| KEY_WRITE
| wow64_access_
);
95 if (result
== ERROR_SUCCESS
) {
96 // try to restore the previous value
97 DWORD previous_size
= static_cast<DWORD
>(previous_value_
.size());
98 const char* previous_value
=
99 previous_size
? &previous_value_
[0] : NULL
;
100 result
= key
.WriteValue(value_name_
.c_str(), previous_value
,
101 previous_size
, previous_type_
);
102 VLOG_IF(1, result
!= ERROR_SUCCESS
) << "rollback: restoring "
103 << value_name_
<< " error: " << result
;
105 VLOG(1) << "can not open " << key_path_
<< " error: " << result
;