| 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 |