OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/installer/util/package.h" | |
6 | |
7 #include "base/file_util.h" | |
8 #include "base/logging.h" | |
9 #include "base/string_util.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "base/win/registry.h" | |
12 #include "chrome/installer/util/delete_tree_work_item.h" | |
13 #include "chrome/installer/util/google_update_constants.h" | |
14 #include "chrome/installer/util/helper.h" | |
15 #include "chrome/installer/util/master_preferences.h" | |
16 #include "chrome/installer/util/package_properties.h" | |
17 #include "chrome/installer/util/product.h" | |
18 #include "chrome/installer/util/util_constants.h" | |
19 #include "chrome/installer/util/work_item_list.h" | |
20 | |
21 using base::win::RegKey; | |
22 using installer::MasterPreferences; | |
23 | |
24 namespace installer { | |
25 | |
26 Package::Package(bool multi_install, bool system_level, const FilePath& path, | |
27 PackageProperties* properties) | |
28 : multi_install_(multi_install), | |
29 system_level_(system_level), | |
30 path_(path), | |
31 properties_(properties) { | |
32 DCHECK(properties_); | |
33 } | |
34 | |
35 Package::~Package() { | |
36 } | |
37 | |
38 const FilePath& Package::path() const { | |
39 return path_; | |
40 } | |
41 | |
42 const Products& Package::products() const { | |
43 return products_; | |
44 } | |
45 | |
46 PackageProperties* Package::properties() const { | |
47 return properties_; | |
48 } | |
49 | |
50 bool Package::IsEqual(const FilePath& path) const { | |
51 return FilePath::CompareEqualIgnoreCase(path_.value(), path.value()); | |
52 } | |
53 | |
54 void Package::AssociateProduct(const Product* product) { | |
55 #ifndef NDEBUG | |
56 for (size_t i = 0; i < products_.size(); ++i) { | |
57 DCHECK_NE(product->distribution()->GetType(), | |
58 products_[i]->distribution()->GetType()); | |
59 } | |
60 #endif | |
61 products_.push_back(product); | |
62 } | |
63 | |
64 bool Package::multi_install() const { | |
65 return multi_install_; | |
66 } | |
67 | |
68 bool Package::system_level() const { | |
69 return system_level_; | |
70 } | |
71 | |
72 FilePath Package::GetInstallerDirectory( | |
73 const Version& version) const { | |
74 return path_.Append(UTF8ToWide(version.GetString())) | |
75 .Append(installer::kInstallerDir); | |
76 } | |
77 | |
78 Version* Package::GetCurrentVersion() const { | |
79 scoped_ptr<Version> current_version; | |
80 // Be aware that there might be a pending "new_chrome.exe" already in the | |
81 // installation path. | |
82 FilePath new_chrome_exe(path_.Append(installer::kChromeNewExe)); | |
83 bool new_chrome_exists = file_util::PathExists(new_chrome_exe); | |
84 | |
85 HKEY root = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
86 | |
87 for (size_t i = 0; i < products_.size(); ++i) { | |
88 const Product* product = products_[i]; | |
89 RegKey chrome_key(root, product->distribution()->GetVersionKey().c_str(), | |
90 KEY_READ); | |
91 std::wstring version; | |
92 if (new_chrome_exists) | |
93 chrome_key.ReadValue(google_update::kRegOldVersionField, &version); | |
94 | |
95 if (version.empty()) | |
96 chrome_key.ReadValue(google_update::kRegVersionField, &version); | |
97 | |
98 if (!version.empty()) { | |
99 scoped_ptr<Version> this_version(Version::GetVersionFromString( | |
100 WideToASCII(version))); | |
101 if (this_version.get()) { | |
102 if (!current_version.get() || | |
103 (current_version->CompareTo(*this_version) > 0)) { | |
104 current_version.reset(this_version.release()); | |
105 } else if (current_version.get()) { | |
106 DCHECK_EQ(current_version->GetString(), this_version->GetString()) | |
107 << "found distributions of different versions in the same " | |
108 "installation folder!"; | |
109 } | |
110 } | |
111 } | |
112 } | |
113 | |
114 return current_version.release(); | |
115 } | |
116 | |
117 void Package::RemoveOldVersionDirectories( | |
118 const Version& latest_version) const { | |
119 file_util::FileEnumerator version_enum(path_, false, | |
120 file_util::FileEnumerator::DIRECTORIES); | |
121 scoped_ptr<Version> version; | |
122 | |
123 // We try to delete all directories whose versions are lower than | |
124 // latest_version. | |
125 FilePath next_version = version_enum.Next(); | |
126 while (!next_version.empty()) { | |
127 file_util::FileEnumerator::FindInfo find_data = {0}; | |
128 version_enum.GetFindInfo(&find_data); | |
129 VLOG(1) << "directory found: " << find_data.cFileName; | |
130 version.reset(Version::GetVersionFromString( | |
131 WideToASCII(find_data.cFileName))); | |
132 if (version.get() && (latest_version.CompareTo(*version) > 0)) { | |
133 std::vector<FilePath> key_files; | |
134 for (Products::const_iterator it = products_.begin(); | |
135 it != products_.end(); ++it) { | |
136 BrowserDistribution* dist = it->get()->distribution(); | |
137 std::vector<FilePath> dist_key_files(dist->GetKeyFiles()); | |
138 std::vector<FilePath>::const_iterator key_file_iter( | |
139 dist_key_files.begin()); | |
140 for (; key_file_iter != dist_key_files.end(); ++key_file_iter) { | |
141 key_files.push_back(next_version.Append(*key_file_iter)); | |
142 } | |
143 } | |
144 | |
145 VLOG(1) << "Deleting directory: " << next_version.value(); | |
146 | |
147 scoped_ptr<DeleteTreeWorkItem> item( | |
148 WorkItem::CreateDeleteTreeWorkItem(next_version, key_files)); | |
149 if (!item->Do()) | |
150 item->Rollback(); | |
151 } | |
152 | |
153 next_version = version_enum.Next(); | |
154 } | |
155 } | |
156 | |
157 size_t Package::GetMultiInstallDependencyCount() const { | |
158 BrowserDistribution::Type product_types[] = { | |
159 BrowserDistribution::CHROME_BROWSER, | |
160 BrowserDistribution::CHROME_FRAME, | |
161 }; | |
162 | |
163 const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); | |
164 HKEY root_key = system_level_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
165 | |
166 size_t ret = 0; | |
167 | |
168 for (int i = 0; i < arraysize(product_types); ++i) { | |
169 BrowserDistribution* dist = | |
170 BrowserDistribution::GetSpecificDistribution(product_types[i], prefs); | |
171 // First see if the product is installed by checking its version key. | |
172 // If the key doesn't exist, the product isn't installed. | |
173 RegKey version_key(root_key, dist->GetVersionKey().c_str(), KEY_READ); | |
174 if (!version_key.Valid()) { | |
175 VLOG(1) << "Product not installed: " << dist->GetApplicationName(); | |
176 } else { | |
177 if (installer::IsInstalledAsMulti(system_level_, dist)) { | |
178 VLOG(1) << "Product dependency: " << dist->GetApplicationName(); | |
179 ++ret; | |
180 } | |
181 } | |
182 } | |
183 | |
184 return ret; | |
185 } | |
186 | |
187 } // namespace installer | |
188 | |
OLD | NEW |