Chromium Code Reviews| 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_); |
|
grt (UTC plus 2)
2014/05/23 01:28:51
facepalm!
Will Harris
2014/05/23 03:19:21
found by tests!
| |
| 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 |