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