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