delete_reg_value_work_item.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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. 4 5#include "chrome/installer/util/delete_reg_value_work_item.h" 6 7#include "base/logging.h" 8#include "base/string_util.h" 9#include "base/win/registry.h" 10#include "chrome/installer/util/logging_installer.h" 11 12using base::win::RegKey; 13 14DeleteRegValueWorkItem::DeleteRegValueWorkItem(HKEY predefined_root, 15 const std::wstring& key_path, 16 const std::wstring& value_name) 17 : predefined_root_(predefined_root), 18 key_path_(key_path), 19 value_name_(value_name), 20 previous_type_(0), 21 status_(DELETE_VALUE) { 22} 23 24DeleteRegValueWorkItem::~DeleteRegValueWorkItem() { 25} 26 27bool DeleteRegValueWorkItem::Do() { 28 if (status_ != DELETE_VALUE) { 29 // we already did something. 30 LOG(ERROR) << "multiple calls to Do()"; 31 return false; 32 } 33 34 status_ = VALUE_UNCHANGED; 35 36 RegKey key; 37 DWORD type = 0; 38 DWORD size = 0; 39 LONG result = key.Open(predefined_root_, key_path_.c_str(), 40 KEY_READ | KEY_WRITE); 41 if (result == ERROR_SUCCESS) 42 result = key.ReadValue(value_name_.c_str(), NULL, &size, &type); 43 44 if (result == ERROR_FILE_NOT_FOUND) { 45 LOG(INFO) << "(delete value) Key: " << key_path_ << " or Value: " 46 << value_name_ << " does not exist."; 47 status_ = VALUE_NOT_FOUND; 48 return true; 49 } 50 51 if (result == ERROR_SUCCESS) { 52 if (!size) { 53 previous_type_ = type; 54 } else { 55 previous_value_.resize(size); 56 result = key.ReadValue(value_name_.c_str(), &previous_value_[0], &size, 57 &previous_type_); 58 if (result != ERROR_SUCCESS) { 59 previous_value_.erase(); 60 VLOG(1) << "Failed to save original value. Error: " << result; 61 } 62 } 63 } 64 65 result = key.DeleteValue(value_name_.c_str()); 66 if (result != ERROR_SUCCESS) { 67 VLOG(1) << "Failed to delete value " << value_name_ << " error: " << result; 68 return false; 69 } 70 71 status_ = VALUE_DELETED; 72 return true; 73} 74 75void DeleteRegValueWorkItem::Rollback() { 76 if (status_ == DELETE_VALUE || status_ == VALUE_ROLLED_BACK) 77 return; 78 if (status_ == VALUE_UNCHANGED || status_ == VALUE_NOT_FOUND) { 79 status_ = VALUE_ROLLED_BACK; 80 VLOG(1) << "rollback: setting unchanged, nothing to do"; 81 return; 82 } 83 84 // At this point only possible state is VALUE_DELETED. 85 RegKey key; 86 LONG result = key.Open(predefined_root_, key_path_.c_str(), 87 KEY_READ | KEY_WRITE); 88 if (result == ERROR_SUCCESS) { 89 // try to restore the previous value 90 DWORD previous_size = static_cast<DWORD>(previous_value_.size()); 91 const char* previous_value = 92 previous_size ? &previous_value_[0] : NULL; 93 result = key.WriteValue(value_name_.c_str(), previous_value, 94 previous_size, previous_type_); 95 VLOG_IF(1, result != ERROR_SUCCESS) << "rollback: restoring " 96 << value_name_ << " error: " << result; 97 } else { 98 VLOG(1) << "can not open " << key_path_ << " error: " << result; 99 } 100} 101