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 "chrome/installer/util/installation_state.h" | 5 #include "chrome/installer/util/installation_state.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/version.h" | 9 #include "base/version.h" |
10 #include "base/win/registry.h" | 10 #include "base/win/registry.h" |
11 #include "chrome/installer/util/google_update_constants.h" | 11 #include "chrome/installer/util/google_update_constants.h" |
12 #include "chrome/installer/util/package_properties.h" | 12 |
13 namespace { | |
14 | |
15 CommandLine MakeUninstallCommand(const std::wstring& setup_path, | |
16 const std::wstring& uninstall_arguments) { | |
robertshield
2011/01/21 16:58:56
This looks non-trivial enough to warrant a small u
grt (UTC plus 2)
2011/01/24 16:07:02
Done.
| |
17 bool no_program = setup_path.empty(); | |
18 | |
19 // Return a bunch of nothingness. | |
20 if (no_program && uninstall_arguments.empty()) | |
21 return CommandLine(CommandLine::NO_PROGRAM); | |
22 | |
23 // Form a full command line string. | |
24 std::wstring command; | |
25 command.append(1, L'"') | |
26 .append(no_program ? L"foo.exe" : setup_path) | |
27 .append(L"\" ") | |
28 .append(uninstall_arguments); | |
29 | |
30 // If we have a program name, return this complete command line. | |
31 if (!no_program) | |
32 return CommandLine::FromString(command); | |
33 | |
34 // Otherwise, make a new instance with the arguments but no program. | |
35 CommandLine result(CommandLine::NO_PROGRAM); | |
36 result.AppendArguments(CommandLine::FromString(command), false); | |
37 return result; | |
38 } | |
39 | |
40 } // namespace | |
13 | 41 |
14 namespace installer { | 42 namespace installer { |
15 | 43 |
16 ProductState::ProductState() { | 44 ProductState::ProductState() |
45 : uninstall_command_(CommandLine::NO_PROGRAM), | |
46 msi_(false), | |
47 multi_install_(false) { | |
17 } | 48 } |
18 | 49 |
19 void ProductState::Initialize(bool system_install, | 50 bool ProductState::Initialize(bool system_install, |
20 const std::wstring& version_key, | 51 BrowserDistribution::Type type) { |
21 const std::wstring& state_key) { | 52 return Initialize(system_install, |
53 BrowserDistribution::GetSpecificDistribution(type)); | |
54 } | |
55 | |
56 bool ProductState::Initialize(bool system_install, | |
57 BrowserDistribution* distribution) { | |
robertshield
2011/01/21 16:58:56
I'd feel better if this had a test too. The test c
grt (UTC plus 2)
2011/01/24 16:07:02
Done; see product_state_unittest.cc.
| |
58 const std::wstring version_key(distribution->GetVersionKey()); | |
59 const std::wstring state_key(distribution->GetStateKey()); | |
22 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 60 const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
23 base::win::RegKey key(root_key, version_key.c_str(), KEY_QUERY_VALUE); | 61 base::win::RegKey key(root_key, version_key.c_str(), KEY_QUERY_VALUE); |
24 std::wstring version_str; | 62 std::wstring version_str; |
25 if (key.ReadValue(google_update::kRegVersionField, &version_str) | 63 if (key.ReadValue(google_update::kRegVersionField, &version_str) |
26 == ERROR_SUCCESS) { | 64 == ERROR_SUCCESS) { |
27 version_.reset(Version::GetVersionFromString(WideToASCII(version_str))); | 65 version_.reset(Version::GetVersionFromString(WideToASCII(version_str))); |
28 if (version_.get() != NULL) { | 66 if (version_.get() != NULL) { |
29 // The product is installed. Check for the channel value (absent if not | 67 // The product is installed. |
30 // installed/managed by Google Update). | 68 if (key.ReadValue(google_update::kRegOldVersionField, &version_str) |
31 if ((key.Open(root_key, state_key.c_str(), KEY_QUERY_VALUE) != | 69 == ERROR_SUCCESS) { |
32 ERROR_SUCCESS) || !channel_.Initialize(key)) { | 70 old_version_.reset( |
33 channel_.set_value(std::wstring()); | 71 Version::GetVersionFromString(WideToASCII(version_str))); |
72 } else { | |
73 old_version_.reset(); | |
74 } | |
75 if (key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd_) | |
76 != ERROR_SUCCESS) | |
robertshield
2011/01/21 16:58:56
NIT WARNING: I find the following more readable:
grt (UTC plus 2)
2011/01/24 16:07:02
I like that better, too. Thanks.
| |
77 rename_cmd_.clear(); | |
78 // Read from the ClientState key. | |
79 channel_.set_value(std::wstring()); | |
80 uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM); | |
81 msi_ = false; | |
82 multi_install_ = false; | |
83 if (key.Open(root_key, state_key.c_str(), KEY_QUERY_VALUE) | |
84 == ERROR_SUCCESS) { | |
85 std::wstring setup_path; | |
86 std::wstring uninstall_arguments; | |
87 // "ap" will be absent if not managed by Google Update. | |
88 channel_.Initialize(key); | |
89 // "UninstallString" will be absent for the multi-installer package. | |
90 key.ReadValue(kUninstallStringField, &setup_path); | |
91 // "UninstallArguments" will be absent for the multi-installer package. | |
92 key.ReadValue(kUninstallArgumentsField, &uninstall_arguments); | |
93 uninstall_command_ = | |
94 MakeUninstallCommand(setup_path, uninstall_arguments); | |
95 // "msi" may be absent, 0 or 1 | |
96 DWORD dw_value = 0; | |
97 msi_ = (key.ReadValueDW(google_update::kRegMSIField, &dw_value) | |
98 == ERROR_SUCCESS) && (dw_value != 0); | |
99 // Multi-install is implied or is derived from the command-line. | |
100 if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES) | |
101 multi_install_ = true; | |
102 else | |
103 multi_install_ = uninstall_command_.HasSwitch( | |
104 switches::kMultiInstall); | |
tommi (sloooow) - chröme
2011/01/21 21:45:17
braces
grt (UTC plus 2)
2011/01/24 16:07:02
Done.
| |
34 } | 105 } |
35 } | 106 } |
36 } else { | 107 } else { |
37 version_.reset(); | 108 version_.reset(); |
38 } | 109 } |
110 return version_.get() != NULL; | |
111 } | |
112 | |
113 FilePath ProductState::GetSetupPath() const { | |
114 return uninstall_command_.GetProgram(); | |
39 } | 115 } |
40 | 116 |
41 const Version& ProductState::version() const { | 117 const Version& ProductState::version() const { |
42 DCHECK(version_.get() != NULL); | 118 DCHECK(version_.get() != NULL); |
43 return *version_; | 119 return *version_; |
44 } | 120 } |
45 | 121 |
46 void ProductState::CopyFrom(const ProductState& other) { | 122 ProductState& ProductState::CopyFrom(const ProductState& other) { |
47 channel_.set_value(other.channel_.value()); | 123 channel_.set_value(other.channel_.value()); |
48 if (other.version_.get() == NULL) | 124 version_.reset(other.version_.get() == NULL ? NULL : other.version_->Clone()); |
49 version_.reset(); | 125 old_version_.reset( |
50 else | 126 other.old_version_.get() == NULL ? NULL : other.old_version_->Clone()); |
51 version_.reset(other.version_->Clone()); | 127 rename_cmd_ = other.rename_cmd_; |
128 uninstall_command_ = other.uninstall_command_; | |
129 msi_ = other.msi_; | |
130 multi_install_ = other.multi_install_; | |
131 | |
132 return *this; | |
52 } | 133 } |
53 | 134 |
54 InstallationState::InstallationState() { | 135 InstallationState::InstallationState() { |
55 } | 136 } |
56 | 137 |
57 // static | 138 // static |
58 int InstallationState::IndexFromDistType(BrowserDistribution::Type type) { | 139 int InstallationState::IndexFromDistType(BrowserDistribution::Type type) { |
59 COMPILE_ASSERT(BrowserDistribution::CHROME_BROWSER == CHROME_BROWSER_INDEX, | 140 COMPILE_ASSERT(BrowserDistribution::CHROME_BROWSER == CHROME_BROWSER_INDEX, |
60 unexpected_chrome_browser_distribution_value_); | 141 unexpected_chrome_browser_distribution_value_); |
61 COMPILE_ASSERT(BrowserDistribution::CHROME_FRAME == CHROME_FRAME_INDEX, | 142 COMPILE_ASSERT(BrowserDistribution::CHROME_FRAME == CHROME_FRAME_INDEX, |
62 unexpected_chrome_frame_distribution_value_); | 143 unexpected_chrome_frame_distribution_value_); |
144 COMPILE_ASSERT(BrowserDistribution::CHROME_BINARIES == CHROME_BINARIES_INDEX, | |
145 unexpected_chrome_frame_distribution_value_); | |
63 DCHECK(type == BrowserDistribution::CHROME_BROWSER || | 146 DCHECK(type == BrowserDistribution::CHROME_BROWSER || |
64 type == BrowserDistribution::CHROME_FRAME); | 147 type == BrowserDistribution::CHROME_FRAME || |
148 type == BrowserDistribution::CHROME_BINARIES); | |
65 return type; | 149 return type; |
66 } | 150 } |
67 | 151 |
68 void InstallationState::Initialize(const MasterPreferences& prefs) { | 152 void InstallationState::Initialize() { |
69 BrowserDistribution* distribution; | 153 BrowserDistribution* distribution; |
70 | 154 |
71 distribution = BrowserDistribution::GetSpecificDistribution( | 155 distribution = BrowserDistribution::GetSpecificDistribution( |
72 BrowserDistribution::CHROME_BROWSER, prefs); | 156 BrowserDistribution::CHROME_BROWSER); |
73 InitializeProduct(false, distribution, &user_products_[CHROME_BROWSER_INDEX]); | 157 user_products_[CHROME_BROWSER_INDEX].Initialize(false, distribution); |
74 InitializeProduct(true, distribution, | 158 system_products_[CHROME_BROWSER_INDEX].Initialize(true, distribution); |
75 &system_products_[CHROME_BROWSER_INDEX]); | |
76 | 159 |
77 distribution = BrowserDistribution::GetSpecificDistribution( | 160 distribution = BrowserDistribution::GetSpecificDistribution( |
78 BrowserDistribution::CHROME_FRAME, prefs); | 161 BrowserDistribution::CHROME_FRAME); |
79 InitializeProduct(false, distribution, &user_products_[CHROME_FRAME_INDEX]); | 162 user_products_[CHROME_FRAME_INDEX].Initialize(false, distribution); |
80 InitializeProduct(true, distribution, &system_products_[CHROME_FRAME_INDEX]); | 163 system_products_[CHROME_FRAME_INDEX].Initialize(true, distribution); |
81 | 164 |
82 ActivePackageProperties package_properties; | 165 distribution = BrowserDistribution::GetSpecificDistribution( |
83 InitializeMultiPackage(false, package_properties, | 166 BrowserDistribution::CHROME_BINARIES); |
84 &user_products_[MULTI_PACKAGE_INDEX]); | 167 user_products_[CHROME_BINARIES_INDEX].Initialize(false, distribution); |
85 InitializeMultiPackage(true, package_properties, | 168 system_products_[CHROME_BINARIES_INDEX].Initialize(true, distribution); |
86 &system_products_[MULTI_PACKAGE_INDEX]); | |
87 } | |
88 | |
89 // static | |
90 void InstallationState::InitializeProduct(bool system_install, | |
91 BrowserDistribution* distribution, | |
92 ProductState* product) { | |
93 product->Initialize(system_install, distribution->GetVersionKey(), | |
94 distribution->GetStateKey()); | |
95 } | |
96 | |
97 // static | |
98 void InstallationState::InitializeMultiPackage(bool system_install, | |
99 PackageProperties& properties, | |
100 ProductState* product) { | |
101 product->Initialize(system_install, properties.GetVersionKey(), | |
102 properties.GetStateKey()); | |
103 } | |
104 | |
105 const ProductState* InstallationState::GetMultiPackageState( | |
106 bool system_install) const { | |
107 const ProductState& product_state = | |
108 (system_install ? system_products_ : user_products_)[MULTI_PACKAGE_INDEX]; | |
109 return product_state.version_.get() == NULL ? NULL : &product_state; | |
110 } | 169 } |
111 | 170 |
112 const ProductState* InstallationState::GetProductState( | 171 const ProductState* InstallationState::GetProductState( |
113 bool system_install, | 172 bool system_install, |
114 BrowserDistribution::Type type) const { | 173 BrowserDistribution::Type type) const { |
115 const ProductState& product_state = (system_install ? system_products_ : | 174 const ProductState& product_state = (system_install ? system_products_ : |
116 user_products_)[IndexFromDistType(type)]; | 175 user_products_)[IndexFromDistType(type)]; |
117 return product_state.version_.get() == NULL ? NULL : &product_state; | 176 return product_state.version_.get() == NULL ? NULL : &product_state; |
118 } | 177 } |
119 | 178 |
120 } // namespace installer | 179 } // namespace installer |
OLD | NEW |