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