Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / installer / util / create_reg_key_work_item.cc
blob69043daff20b6ab0b01e490dd61417cd0d33d0b1
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
3 // found in the LICENSE file.
5 #include <shlwapi.h>
7 #include "base/files/file_path.h"
8 #include "base/logging.h"
9 #include "base/win/registry.h"
10 #include "chrome/installer/util/create_reg_key_work_item.h"
11 #include "chrome/installer/util/install_util.h"
12 #include "chrome/installer/util/logging_installer.h"
14 using base::win::RegKey;
16 namespace {
18 // TODO: refactor this because it is only used once.
19 void UpOneDirectoryOrEmpty(std::wstring* dir) {
20 base::FilePath path = base::FilePath(*dir);
21 base::FilePath directory = path.DirName();
22 // If there is no separator, we will get back kCurrentDirectory.
23 // In this case, clear dir.
24 if (directory == path || directory.value() ==
25 base::FilePath::kCurrentDirectory)
26 dir->clear();
27 else
28 *dir = directory.value();
31 } // namespace
33 CreateRegKeyWorkItem::~CreateRegKeyWorkItem() {
36 CreateRegKeyWorkItem::CreateRegKeyWorkItem(HKEY predefined_root,
37 const std::wstring& path)
38 : predefined_root_(predefined_root),
39 path_(path),
40 key_created_(false) {
43 bool CreateRegKeyWorkItem::Do() {
44 if (!InitKeyList()) {
45 // Nothing needs to be done here.
46 VLOG(1) << "no key to create";
47 return true;
50 RegKey key;
51 std::wstring key_path;
53 // To create keys, we iterate from back to front.
54 for (size_t i = key_list_.size(); i > 0; i--) {
55 DWORD disposition;
56 key_path.assign(key_list_[i - 1]);
58 if (key.CreateWithDisposition(predefined_root_, key_path.c_str(),
59 &disposition, KEY_READ) == ERROR_SUCCESS) {
60 if (disposition == REG_OPENED_EXISTING_KEY) {
61 if (key_created_) {
62 // This should not happen. Someone created a subkey under the key
63 // we just created?
64 LOG(ERROR) << key_path << " exists, this is not expected.";
65 return false;
67 // Remove the key path from list if it is already present.
68 key_list_.pop_back();
69 } else if (disposition == REG_CREATED_NEW_KEY) {
70 VLOG(1) << "created " << key_path;
71 key_created_ = true;
72 } else {
73 LOG(ERROR) << "unkown disposition";
74 return false;
76 } else {
77 LOG(ERROR) << "Failed to create " << key_path;
78 return false;
82 return true;
85 void CreateRegKeyWorkItem::Rollback() {
86 if (!key_created_)
87 return;
89 std::wstring key_path;
90 // To delete keys, we iterate from front to back.
91 std::vector<std::wstring>::iterator itr;
92 for (itr = key_list_.begin(); itr != key_list_.end(); ++itr) {
93 key_path.assign(*itr);
94 if (SHDeleteEmptyKey(predefined_root_, key_path.c_str()) ==
95 ERROR_SUCCESS) {
96 VLOG(1) << "rollback: delete " << key_path;
97 } else {
98 VLOG(1) << "rollback: can not delete " << key_path;
99 // The key might have been deleted, but we don't reliably know what
100 // error code(s) are returned in this case. So we just keep tring delete
101 // the rest.
105 key_created_ = false;
106 key_list_.clear();
107 return;
110 bool CreateRegKeyWorkItem::InitKeyList() {
111 if (path_.empty())
112 return false;
114 std::wstring key_path(path_);
116 do {
117 key_list_.push_back(key_path);
118 // This is pure string operation so it does not matter whether the
119 // path is file path or registry path.
120 UpOneDirectoryOrEmpty(&key_path);
121 } while (!key_path.empty());
123 return true;