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 <shlwapi.h> | 5 #include <shlwapi.h> |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/win/registry.h" | 9 #include "base/win/registry.h" |
10 #include "chrome/installer/util/create_reg_key_work_item.h" | 10 #include "chrome/installer/util/create_reg_key_work_item.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 else | 27 else |
28 *dir = directory.value(); | 28 *dir = directory.value(); |
29 } | 29 } |
30 | 30 |
31 } // namespace | 31 } // namespace |
32 | 32 |
33 CreateRegKeyWorkItem::~CreateRegKeyWorkItem() { | 33 CreateRegKeyWorkItem::~CreateRegKeyWorkItem() { |
34 } | 34 } |
35 | 35 |
36 CreateRegKeyWorkItem::CreateRegKeyWorkItem(HKEY predefined_root, | 36 CreateRegKeyWorkItem::CreateRegKeyWorkItem(HKEY predefined_root, |
37 const std::wstring& path) | 37 const std::wstring& path, |
| 38 REGSAM wow64_access) |
38 : predefined_root_(predefined_root), | 39 : predefined_root_(predefined_root), |
39 path_(path), | 40 path_(path), |
| 41 wow64_access_(wow64_access), |
40 key_created_(false) { | 42 key_created_(false) { |
| 43 DCHECK(wow64_access == 0 || |
| 44 wow64_access == KEY_WOW64_32KEY || |
| 45 wow64_access == KEY_WOW64_64KEY); |
41 } | 46 } |
42 | 47 |
43 bool CreateRegKeyWorkItem::Do() { | 48 bool CreateRegKeyWorkItem::Do() { |
44 if (!InitKeyList()) { | 49 if (!InitKeyList()) { |
45 // Nothing needs to be done here. | 50 // Nothing needs to be done here. |
46 VLOG(1) << "no key to create"; | 51 VLOG(1) << "no key to create"; |
47 return true; | 52 return true; |
48 } | 53 } |
49 | 54 |
50 RegKey key; | 55 RegKey key; |
51 std::wstring key_path; | 56 std::wstring key_path; |
52 | 57 |
53 // To create keys, we iterate from back to front. | 58 // To create keys, we iterate from back to front. |
54 for (size_t i = key_list_.size(); i > 0; i--) { | 59 for (size_t i = key_list_.size(); i > 0; i--) { |
55 DWORD disposition; | 60 DWORD disposition; |
56 key_path.assign(key_list_[i - 1]); | 61 key_path.assign(key_list_[i - 1]); |
57 | 62 |
58 if (key.CreateWithDisposition(predefined_root_, key_path.c_str(), | 63 if (key.CreateWithDisposition(predefined_root_, |
59 &disposition, KEY_READ) == ERROR_SUCCESS) { | 64 key_path.c_str(), |
| 65 &disposition, |
| 66 KEY_READ | wow64_access_) == ERROR_SUCCESS) { |
60 if (disposition == REG_OPENED_EXISTING_KEY) { | 67 if (disposition == REG_OPENED_EXISTING_KEY) { |
61 if (key_created_) { | 68 if (key_created_) { |
62 // This should not happen. Someone created a subkey under the key | 69 // This should not happen. Someone created a subkey under the key |
63 // we just created? | 70 // we just created? |
64 LOG(ERROR) << key_path << " exists, this is not expected."; | 71 LOG(ERROR) << key_path << " exists, this is not expected."; |
65 return false; | 72 return false; |
66 } | 73 } |
67 // Remove the key path from list if it is already present. | 74 // Remove the key path from list if it is already present. |
68 key_list_.pop_back(); | 75 key_list_.pop_back(); |
69 } else if (disposition == REG_CREATED_NEW_KEY) { | 76 } else if (disposition == REG_CREATED_NEW_KEY) { |
(...skipping 14 matching lines...) Expand all Loading... |
84 | 91 |
85 void CreateRegKeyWorkItem::Rollback() { | 92 void CreateRegKeyWorkItem::Rollback() { |
86 if (!key_created_) | 93 if (!key_created_) |
87 return; | 94 return; |
88 | 95 |
89 std::wstring key_path; | 96 std::wstring key_path; |
90 // To delete keys, we iterate from front to back. | 97 // To delete keys, we iterate from front to back. |
91 std::vector<std::wstring>::iterator itr; | 98 std::vector<std::wstring>::iterator itr; |
92 for (itr = key_list_.begin(); itr != key_list_.end(); ++itr) { | 99 for (itr = key_list_.begin(); itr != key_list_.end(); ++itr) { |
93 key_path.assign(*itr); | 100 key_path.assign(*itr); |
94 if (SHDeleteEmptyKey(predefined_root_, key_path.c_str()) == | 101 RegKey key(predefined_root_, L"", KEY_WRITE & wow64_access_); |
95 ERROR_SUCCESS) { | 102 if (key.DeleteEmptyKey(key_path.c_str()) == ERROR_SUCCESS) { |
96 VLOG(1) << "rollback: delete " << key_path; | 103 VLOG(1) << "rollback: delete " << key_path; |
97 } else { | 104 } else { |
98 VLOG(1) << "rollback: can not delete " << key_path; | 105 VLOG(1) << "rollback: can not delete " << key_path; |
99 // The key might have been deleted, but we don't reliably know what | 106 // 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 | 107 // error code(s) are returned in this case. So we just keep tring delete |
101 // the rest. | 108 // the rest. |
102 } | 109 } |
103 } | 110 } |
104 | 111 |
105 key_created_ = false; | 112 key_created_ = false; |
106 key_list_.clear(); | 113 key_list_.clear(); |
107 return; | 114 return; |
108 } | 115 } |
109 | 116 |
110 bool CreateRegKeyWorkItem::InitKeyList() { | 117 bool CreateRegKeyWorkItem::InitKeyList() { |
111 if (path_.empty()) | 118 if (path_.empty()) |
112 return false; | 119 return false; |
113 | 120 |
114 std::wstring key_path(path_); | 121 std::wstring key_path(path_); |
115 | 122 |
116 do { | 123 do { |
117 key_list_.push_back(key_path); | 124 key_list_.push_back(key_path); |
118 // This is pure string operation so it does not matter whether the | 125 // This is pure string operation so it does not matter whether the |
119 // path is file path or registry path. | 126 // path is file path or registry path. |
120 UpOneDirectoryOrEmpty(&key_path); | 127 UpOneDirectoryOrEmpty(&key_path); |
121 } while (!key_path.empty()); | 128 } while (!key_path.empty()); |
122 | 129 |
123 return true; | 130 return true; |
124 } | 131 } |
OLD | NEW |