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 // This file declares utility functions for the installer. The original reason 6 // for putting these functions in installer\util library is so that we can 7 // separate out the critical logic and write unit tests for it. 8 9 #ifndef CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_ 10 #define CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_ 11 12 #include <windows.h> 13 #include <tchar.h> 14 15 #include "base/basictypes.h" 16 #include "base/command_line.h" 17 #include "base/files/file_path.h" 18 #include "base/strings/string16.h" 19 #include "base/win/scoped_handle.h" 20 #include "chrome/installer/util/browser_distribution.h" 21 #include "chrome/installer/util/util_constants.h" 22 23 class WorkItemList; 24 25 namespace base { 26 class Version; 27 } 28 29 // This is a utility class that provides common installation related 30 // utility methods that can be used by installer and also unit tested 31 // independently. 32 class InstallUtil { 33 public: 34 // Get the path to this distribution's Active Setup registry entries. 35 // e.g. Software\Microsoft\Active Setup\Installed Components\<dist_guid> 36 static string16 GetActiveSetupPath(BrowserDistribution* dist); 37 38 // Attempts to trigger the command that would be run by Active Setup for a 39 // system-level Chrome. For use only when system-level Chrome is installed. 40 static void TriggerActiveSetupCommand(); 41 42 // Launches given exe as admin on Vista. 43 static bool ExecuteExeAsAdmin(const CommandLine& cmd, DWORD* exit_code); 44 45 // Reads the uninstall command for Chromium from registry and returns it. 46 // If system_install is true the command is read from HKLM, otherwise 47 // from HKCU. 48 static CommandLine GetChromeUninstallCmd( 49 bool system_install, 50 BrowserDistribution::Type distribution_type); 51 52 // Find the version of Chrome installed on the system by checking the 53 // Google Update registry key. Fills |version| with the version or a 54 // default-constructed Version if no version is found. 55 // system_install: if true, looks for version number under the HKLM root, 56 // otherwise looks under the HKCU. 57 static void GetChromeVersion(BrowserDistribution* dist, 58 bool system_install, 59 base::Version* version); 60 61 // Find the last critical update (version) of Chrome. Fills |version| with the 62 // version or a default-constructed Version if no version is found. A critical 63 // update is a specially flagged version (by Google Update) that contains an 64 // important security fix. 65 // system_install: if true, looks for version number under the HKLM root, 66 // otherwise looks under the HKCU. 67 static void GetCriticalUpdateVersion(BrowserDistribution* dist, 68 bool system_install, 69 base::Version* version); 70 71 // This function checks if the current OS is supported for Chromium. 72 static bool IsOSSupported(); 73 74 // Adds work items to |install_list|, which should be a 75 // NoRollbackWorkItemList, to set installer error information in the registry 76 // for consumption by Google Update. |state_key| must be the full path to an 77 // app's ClientState key. See InstallerState::WriteInstallerResult for more 78 // details. 79 static void AddInstallerResultItems(bool system_install, 80 const string16& state_key, 81 installer::InstallStatus status, 82 int string_resource_id, 83 const string16* const launch_cmd, 84 WorkItemList* install_list); 85 86 // Update the installer stage reported by Google Update. |state_key_path| 87 // should be obtained via the state_key method of an InstallerState instance 88 // created before the machine state is modified by the installer. 89 static void UpdateInstallerStage(bool system_install, 90 const string16& state_key_path, 91 installer::InstallerStage stage); 92 93 // Returns true if this installation path is per user, otherwise returns 94 // false (per machine install, meaning: the exe_path contains path to 95 // Program Files). 96 static bool IsPerUserInstall(const wchar_t* const exe_path); 97 98 // Returns true if the installation represented by the pair of |dist| and 99 // |system_level| is a multi install. 100 static bool IsMultiInstall(BrowserDistribution* dist, bool system_install); 101 102 // Returns true if this is running setup process for Chrome SxS (as 103 // indicated by the presence of --chrome-sxs on the command line) or if this 104 // is running Chrome process from the Chrome SxS installation (as indicated 105 // by either --chrome-sxs or the executable path). 106 static bool IsChromeSxSProcess(); 107 108 // Populates |path| with the path to |file| in the sentinel directory. This is 109 // the application directory for user-level installs, and the default user 110 // data dir for system-level installs. Returns false on error. 111 static bool GetSentinelFilePath(const base::FilePath::CharType* file, 112 BrowserDistribution* dist, 113 base::FilePath* path); 114 115 // Deletes the registry key at path key_path under the key given by root_key. 116 static bool DeleteRegistryKey(HKEY root_key, const string16& key_path); 117 118 // Deletes the registry value named value_name at path key_path under the key 119 // given by reg_root. 120 static bool DeleteRegistryValue(HKEY reg_root, const string16& key_path, 121 const string16& value_name); 122 123 // An interface to a predicate function for use by DeleteRegistryKeyIf and 124 // DeleteRegistryValueIf. 125 class RegistryValuePredicate { 126 public: 127 virtual ~RegistryValuePredicate() { } 128 virtual bool Evaluate(const string16& value) const = 0; 129 }; 130 131 // The result of a conditional delete operation (i.e., DeleteFOOIf). 132 enum ConditionalDeleteResult { 133 NOT_FOUND, // The condition was not satisfied. 134 DELETED, // The condition was satisfied and the delete succeeded. 135 DELETE_FAILED // The condition was satisfied but the delete failed. 136 }; 137 138 // Deletes the key |key_to_delete_path| under |root_key| iff the value 139 // |value_name| in the key |key_to_test_path| under |root_key| satisfies 140 // |predicate|. |value_name| may be either NULL or an empty string to test 141 // the key's default value. 142 static ConditionalDeleteResult DeleteRegistryKeyIf( 143 HKEY root_key, 144 const string16& key_to_delete_path, 145 const string16& key_to_test_path, 146 const wchar_t* value_name, 147 const RegistryValuePredicate& predicate); 148 149 // Deletes the value |value_name| in the key |key_path| under |root_key| iff 150 // its current value satisfies |predicate|. |value_name| may be either NULL 151 // or an empty string to test/delete the key's default value. 152 static ConditionalDeleteResult DeleteRegistryValueIf( 153 HKEY root_key, 154 const wchar_t* key_path, 155 const wchar_t* value_name, 156 const RegistryValuePredicate& predicate); 157 158 // A predicate that performs a case-sensitive string comparison. 159 class ValueEquals : public RegistryValuePredicate { 160 public: 161 explicit ValueEquals(const string16& value_to_match) 162 : value_to_match_(value_to_match) { } 163 virtual bool Evaluate(const string16& value) const OVERRIDE; 164 protected: 165 string16 value_to_match_; 166 private: 167 DISALLOW_COPY_AND_ASSIGN(ValueEquals); 168 }; 169 170 // Returns zero on install success, or an InstallStatus value otherwise. 171 static int GetInstallReturnCode(installer::InstallStatus install_status); 172 173 // Composes |program| and |arguments| into |command_line|. 174 static void MakeUninstallCommand(const string16& program, 175 const string16& arguments, 176 CommandLine* command_line); 177 178 // Returns a string in the form YYYYMMDD of the current date. 179 static string16 GetCurrentDate(); 180 181 // A predicate that compares the program portion of a command line with a 182 // given file path. First, the file paths are compared directly. If they do 183 // not match, the filesystem is consulted to determine if the paths reference 184 // the same file. 185 class ProgramCompare : public RegistryValuePredicate { 186 public: 187 explicit ProgramCompare(const base::FilePath& path_to_match); 188 virtual ~ProgramCompare(); 189 virtual bool Evaluate(const string16& value) const OVERRIDE; 190 bool EvaluatePath(const base::FilePath& path) const; 191 192 protected: 193 static bool OpenForInfo(const base::FilePath& path, 194 base::win::ScopedHandle* handle); 195 static bool GetInfo(const base::win::ScopedHandle& handle, 196 BY_HANDLE_FILE_INFORMATION* info); 197 198 base::FilePath path_to_match_; 199 base::win::ScopedHandle file_handle_; 200 BY_HANDLE_FILE_INFORMATION file_info_; 201 202 private: 203 DISALLOW_COPY_AND_ASSIGN(ProgramCompare); 204 }; // class ProgramCompare 205 206 private: 207 DISALLOW_COPY_AND_ASSIGN(InstallUtil); 208 }; 209 210 211 #endif // CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_ 212