1 // Copyright (c) 2012 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 #ifndef CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_ 6 #define CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_ 7 8 #include <set> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/files/file_path.h" 14 #include "base/logging.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_vector.h" 17 #include "base/version.h" 18 #include "chrome/installer/util/browser_distribution.h" 19 #include "chrome/installer/util/product.h" 20 #include "chrome/installer/util/util_constants.h" 21 22 #if defined(OS_WIN) 23 #include <windows.h> // NOLINT 24 #endif 25 26 namespace base { 27 class CommandLine; 28 } 29 30 namespace installer { 31 32 class ChannelInfo; 33 class InstallationState; 34 class MasterPreferences; 35 36 class ProductState; 37 38 typedef std::vector<Product*> Products; 39 40 // Encapsulates the state of the current installation operation. Only valid 41 // for installs and upgrades (not for uninstalls or non-install commands). 42 // This class interprets the command-line arguments and master preferences and 43 // determines the operations to be performed. For example, the Chrome Binaries 44 // are automatically added if required in multi-install mode. 45 // TODO(erikwright): This is now used a fair bit during uninstall, and 46 // InstallerState::Initialize() contains a lot of code for uninstall. The class 47 // comment should probably be updated. 48 // TODO(grt): Rename to InstallerEngine/Conductor or somesuch? 49 class InstallerState { 50 public: 51 enum Level { 52 UNKNOWN_LEVEL, 53 USER_LEVEL, 54 SYSTEM_LEVEL 55 }; 56 57 enum PackageType { 58 UNKNOWN_PACKAGE_TYPE, 59 SINGLE_PACKAGE, 60 MULTI_PACKAGE 61 }; 62 63 enum Operation { 64 UNINITIALIZED, 65 SINGLE_INSTALL_OR_UPDATE, 66 MULTI_INSTALL, 67 MULTI_UPDATE, 68 UNINSTALL 69 }; 70 71 // Constructs an uninitialized instance; see Initialize(). 72 InstallerState(); 73 74 // Constructs an initialized but empty instance. 75 explicit InstallerState(Level level); 76 77 // Initializes this object based on the current operation. 78 void Initialize(const base::CommandLine& command_line, 79 const MasterPreferences& prefs, 80 const InstallationState& machine_state); 81 82 // Adds a product constructed on the basis of |state|, setting this object's 83 // msi flag if |state| is msi-installed. Returns the product that was added, 84 // or NULL if |state| is incompatible with this object. Ownership is not 85 // passed to the caller. 86 Product* AddProductFromState(BrowserDistribution::Type type, 87 const ProductState& state); 88 89 // Returns the product that was added, or NULL if |product| is incompatible 90 // with this object. Ownership of |product| is taken by this object, while 91 // ownership of the return value is not passed to the caller. 92 Product* AddProduct(scoped_ptr<Product>* product); 93 94 // Removes |product| from the set of products to be operated on. The object 95 // pointed to by |product| is freed. Returns false if |product| is not 96 // present in the set. 97 bool RemoveProduct(const Product* product); 98 99 // The level (user or system) of this operation. 100 Level level() const { return level_; } 101 102 // The package type (single or multi) of this operation. 103 PackageType package_type() const { return package_type_; } 104 105 // An identifier of this operation. 106 Operation operation() const { return operation_; } 107 108 // A convenience method returning level() == SYSTEM_LEVEL. 109 // TODO(grt): Eradicate the bool in favor of the enum. 110 bool system_install() const; 111 112 // A convenience method returning package_type() == MULTI_PACKAGE. 113 // TODO(grt): Eradicate the bool in favor of the enum. 114 bool is_multi_install() const; 115 116 // A convenient method returning the presence of the 117 // --ensure-google-update-present switch. 118 bool ensure_google_update_present() const { 119 return ensure_google_update_present_; 120 } 121 122 // The full path to the place where the operand resides. 123 const base::FilePath& target_path() const { return target_path_; } 124 125 // True if the "msi" preference is set or if a product with the "msi" state 126 // flag is set is to be operated on. 127 bool is_msi() const { return msi_; } 128 129 // True if the --verbose-logging command-line flag is set or if the 130 // verbose_logging master preferences option is true. 131 bool verbose_logging() const { return verbose_logging_; } 132 133 #if defined(OS_WIN) 134 HKEY root_key() const { return root_key_; } 135 #endif 136 137 // The ClientState key by which we interact with Google Update. 138 const std::wstring& state_key() const { return state_key_; } 139 140 // Convenience method to return the type of the BrowserDistribution associated 141 // with the ClientState key we will be interacting with. 142 BrowserDistribution::Type state_type() const { return state_type_; } 143 144 // Returns the BrowserDistribution instance corresponding to the binaries for 145 // this run if we're operating on a multi-package product. 146 BrowserDistribution* multi_package_binaries_distribution() const { 147 DCHECK(package_type_ == MULTI_PACKAGE); 148 DCHECK(multi_package_distribution_ != NULL); 149 return multi_package_distribution_; 150 } 151 152 const Products& products() const { return products_.get(); } 153 154 // Returns the product of the desired type, or NULL if none found. 155 const Product* FindProduct(BrowserDistribution::Type distribution_type) const; 156 157 // Returns the currently installed version in |target_path|, or NULL if no 158 // products are installed. Ownership is passed to the caller. 159 base::Version* GetCurrentVersion( 160 const InstallationState& machine_state) const; 161 162 // Returns the critical update version if all of the following are true: 163 // * --critical-update-version=CUV was specified on the command-line. 164 // * current_version == NULL or current_version < CUV. 165 // * new_version >= CUV. 166 // Otherwise, returns an invalid version. 167 base::Version DetermineCriticalVersion( 168 const base::Version* current_version, 169 const base::Version& new_version) const; 170 171 // Returns whether or not there is currently a Chrome Frame instance running. 172 // Note that there isn't a mechanism to lock Chrome Frame in place, so Chrome 173 // Frame may either exit or start up after this is called. 174 bool IsChromeFrameRunning(const InstallationState& machine_state) const; 175 176 // Returns true if any of the binaries from a multi-install Chrome Frame that 177 // has been migrated to single-install are still in use. 178 bool AreBinariesInUse(const InstallationState& machine_state) const; 179 180 // Returns the path to the installer under Chrome version folder 181 // (for example <target_path>\Google\Chrome\Application\<Version>\Installer) 182 base::FilePath GetInstallerDirectory(const base::Version& version) const; 183 184 // Try to delete all directories under |temp_path| whose versions are less 185 // than |new_version| and not equal to |existing_version|. |existing_version| 186 // may be NULL. 187 void RemoveOldVersionDirectories(const base::Version& new_version, 188 base::Version* existing_version, 189 const base::FilePath& temp_path) const; 190 191 // Adds to |com_dll_list| the list of COM DLLs that are to be registered 192 // and/or unregistered. The list may be empty. 193 void AddComDllList(std::vector<base::FilePath>* com_dll_list) const; 194 195 bool SetChannelFlags(bool set, ChannelInfo* channel_info) const; 196 197 // See InstallUtil::UpdateInstallerStage. 198 void UpdateStage(installer::InstallerStage stage) const; 199 200 // For a MULTI_INSTALL or MULTI_UPDATE operation, updates the Google Update 201 // "ap" values for all products being operated on. 202 void UpdateChannels() const; 203 204 // Sets installer result information in the registry for consumption by Google 205 // Update. The InstallerResult value is set to 0 (SUCCESS) or 1 206 // (FAILED_CUSTOM_ERROR) depending on whether |status| maps to success or not. 207 // |status| itself is written to the InstallerError value. 208 // |string_resource_id|, if non-zero, identifies a localized string written to 209 // the InstallerResultUIString value. |launch_cmd|, if non-NULL and 210 // non-empty, is written to the InstallerSuccessLaunchCmdLine value. 211 void WriteInstallerResult(InstallStatus status, 212 int string_resource_id, 213 const std::wstring* launch_cmd) const; 214 215 // Returns true if this install needs to register an Active Setup command. 216 bool RequiresActiveSetup() const; 217 218 protected: 219 // Bits for the |file_bits| argument of AnyExistsAndIsInUse. 220 enum { 221 CHROME_DLL = 1 << 0, 222 CHROME_FRAME_DLL = 1 << 1, 223 CHROME_FRAME_HELPER_DLL = 1 << 2, 224 CHROME_FRAME_HELPER_EXE = 1 << 3, 225 NUM_BINARIES = 4 226 }; 227 228 // Returns true if |file| exists and cannot be opened for exclusive write 229 // access. 230 static bool IsFileInUse(const base::FilePath& file); 231 232 // Clears the instance to an uninitialized state. 233 void Clear(); 234 235 // Returns true if any file corresponding to a bit in |file_bits| (from the 236 // enum above) for the currently installed version exists and is in use. 237 bool AnyExistsAndIsInUse(const InstallationState& machine_state, 238 uint32 file_bits) const; 239 base::FilePath GetDefaultProductInstallPath(BrowserDistribution* dist) const; 240 bool CanAddProduct(const Product& product, 241 const base::FilePath* product_dir) const; 242 Product* AddProductInDirectory(const base::FilePath* product_dir, 243 scoped_ptr<Product>* product); 244 Product* AddProductFromPreferences( 245 BrowserDistribution::Type distribution_type, 246 const MasterPreferences& prefs, 247 const InstallationState& machine_state); 248 bool IsMultiInstallUpdate(const MasterPreferences& prefs, 249 const InstallationState& machine_state); 250 251 // Enumerates all files named one of 252 // [chrome.exe, old_chrome.exe, new_chrome.exe] in target_path_ and 253 // returns their version numbers in a set. 254 void GetExistingExeVersions(std::set<std::string>* existing_versions) const; 255 256 // Sets this object's level and updates the root_key_ accordingly. 257 void set_level(Level level); 258 259 // Sets this object's package type and updates the multi_package_distribution_ 260 // accordingly. 261 void set_package_type(PackageType type); 262 263 Operation operation_; 264 base::FilePath target_path_; 265 std::wstring state_key_; 266 BrowserDistribution::Type state_type_; 267 ScopedVector<Product> products_; 268 BrowserDistribution* multi_package_distribution_; 269 base::Version critical_update_version_; 270 Level level_; 271 PackageType package_type_; 272 #if defined(OS_WIN) 273 HKEY root_key_; 274 #endif 275 bool msi_; 276 bool verbose_logging_; 277 bool ensure_google_update_present_; 278 279 private: 280 DISALLOW_COPY_AND_ASSIGN(InstallerState); 281 }; // class InstallerState 282 283 } // namespace installer 284 285 #endif // CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_ 286