summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util/install_util.h
blob: 1ea0edd36955c7f54bbd0bed7d0280d1fffbeb42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file declares utility functions for the installer. The original reason
// for putting these functions in installer\util library is so that we can
// separate out the critical logic and write unit tests for it.

#ifndef CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_
#define CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_

#include <windows.h>
#include <tchar.h>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/strings/string16.h"
#include "base/win/scoped_handle.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/util_constants.h"

class WorkItemList;

namespace base {
class Version;
}

// This is a utility class that provides common installation related
// utility methods that can be used by installer and also unit tested
// independently.
class InstallUtil {
 public:
  // Get the path to this distribution's Active Setup registry entries.
  // e.g. Software\Microsoft\Active Setup\Installed Components\<dist_guid>
  static base::string16 GetActiveSetupPath(BrowserDistribution* dist);

  // Attempts to trigger the command that would be run by Active Setup for a
  // system-level Chrome. For use only when system-level Chrome is installed.
  static void TriggerActiveSetupCommand();

  // Launches given exe as admin on Vista.
  static bool ExecuteExeAsAdmin(const CommandLine& cmd, DWORD* exit_code);

  // Reads the uninstall command for Chromium from registry and returns it.
  // If system_install is true the command is read from HKLM, otherwise
  // from HKCU.
  static CommandLine GetChromeUninstallCmd(
      bool system_install,
      BrowserDistribution::Type distribution_type);

  // Find the version of Chrome installed on the system by checking the
  // Google Update registry key. Fills |version| with the version or a
  // default-constructed Version if no version is found.
  // system_install: if true, looks for version number under the HKLM root,
  //                 otherwise looks under the HKCU.
  static void GetChromeVersion(BrowserDistribution* dist,
                               bool system_install,
                               base::Version* version);

  // Find the last critical update (version) of Chrome. Fills |version| with the
  // version or a default-constructed Version if no version is found. A critical
  // update is a specially flagged version (by Google Update) that contains an
  // important security fix.
  // system_install: if true, looks for version number under the HKLM root,
  //                 otherwise looks under the HKCU.
  static void GetCriticalUpdateVersion(BrowserDistribution* dist,
                                       bool system_install,
                                       base::Version* version);

  // This function checks if the current OS is supported for Chromium.
  static bool IsOSSupported();

  // Adds work items to |install_list|, which should be a
  // NoRollbackWorkItemList, to set installer error information in the registry
  // for consumption by Google Update.  |state_key| must be the full path to an
  // app's ClientState key.  See InstallerState::WriteInstallerResult for more
  // details.
  static void AddInstallerResultItems(bool system_install,
                                      const base::string16& state_key,
                                      installer::InstallStatus status,
                                      int string_resource_id,
                                      const base::string16* const launch_cmd,
                                      WorkItemList* install_list);

  // Update the installer stage reported by Google Update.  |state_key_path|
  // should be obtained via the state_key method of an InstallerState instance
  // created before the machine state is modified by the installer.
  static void UpdateInstallerStage(bool system_install,
                                   const base::string16& state_key_path,
                                   installer::InstallerStage stage);

  // Returns true if this installation path is per user, otherwise returns
  // false (per machine install, meaning: the exe_path contains path to
  // Program Files).
  static bool IsPerUserInstall(const wchar_t* const exe_path);

  // Returns true if the installation represented by the pair of |dist| and
  // |system_level| is a multi install.
  static bool IsMultiInstall(BrowserDistribution* dist, bool system_install);

  // Returns true if this is running setup process for Chrome SxS (as
  // indicated by the presence of --chrome-sxs on the command line) or if this
  // is running Chrome process from the Chrome SxS installation (as indicated
  // by either --chrome-sxs or the executable path).
  static bool IsChromeSxSProcess();

  // Populates |path| with the path to |file| in the sentinel directory for
  // |dist|. Returns false on error.
  static bool GetSentinelFilePath(const base::FilePath::CharType* file,
                                  BrowserDistribution* dist,
                                  base::FilePath* path);

  // Deletes the registry key at path key_path under the key given by root_key.
  static bool DeleteRegistryKey(HKEY root_key, const base::string16& key_path);

  // Deletes the registry value named value_name at path key_path under the key
  // given by reg_root.
  static bool DeleteRegistryValue(HKEY reg_root, const base::string16& key_path,
                                  const base::string16& value_name);

  // An interface to a predicate function for use by DeleteRegistryKeyIf and
  // DeleteRegistryValueIf.
  class RegistryValuePredicate {
   public:
    virtual ~RegistryValuePredicate() { }
    virtual bool Evaluate(const base::string16& value) const = 0;
  };

  // The result of a conditional delete operation (i.e., DeleteFOOIf).
  enum ConditionalDeleteResult {
    NOT_FOUND,      // The condition was not satisfied.
    DELETED,        // The condition was satisfied and the delete succeeded.
    DELETE_FAILED   // The condition was satisfied but the delete failed.
  };

  // Deletes the key |key_to_delete_path| under |root_key| iff the value
  // |value_name| in the key |key_to_test_path| under |root_key| satisfies
  // |predicate|.  |value_name| may be either NULL or an empty string to test
  // the key's default value.
  static ConditionalDeleteResult DeleteRegistryKeyIf(
      HKEY root_key,
      const base::string16& key_to_delete_path,
      const base::string16& key_to_test_path,
      const wchar_t* value_name,
      const RegistryValuePredicate& predicate);

  // Deletes the value |value_name| in the key |key_path| under |root_key| iff
  // its current value satisfies |predicate|.  |value_name| may be either NULL
  // or an empty string to test/delete the key's default value.
  static ConditionalDeleteResult DeleteRegistryValueIf(
      HKEY root_key,
      const wchar_t* key_path,
      const wchar_t* value_name,
      const RegistryValuePredicate& predicate);

  // A predicate that performs a case-sensitive string comparison.
  class ValueEquals : public RegistryValuePredicate {
   public:
    explicit ValueEquals(const base::string16& value_to_match)
        : value_to_match_(value_to_match) { }
    virtual bool Evaluate(const base::string16& value) const OVERRIDE;
   protected:
    base::string16 value_to_match_;
   private:
    DISALLOW_COPY_AND_ASSIGN(ValueEquals);
  };

  // Returns zero on install success, or an InstallStatus value otherwise.
  static int GetInstallReturnCode(installer::InstallStatus install_status);

  // Composes |program| and |arguments| into |command_line|.
  static void MakeUninstallCommand(const base::string16& program,
                                   const base::string16& arguments,
                                   CommandLine* command_line);

  // Returns a string in the form YYYYMMDD of the current date.
  static base::string16 GetCurrentDate();

  // A predicate that compares the program portion of a command line with a
  // given file path.  First, the file paths are compared directly.  If they do
  // not match, the filesystem is consulted to determine if the paths reference
  // the same file.
  class ProgramCompare : public RegistryValuePredicate {
   public:
    explicit ProgramCompare(const base::FilePath& path_to_match);
    virtual ~ProgramCompare();
    virtual bool Evaluate(const base::string16& value) const OVERRIDE;
    bool EvaluatePath(const base::FilePath& path) const;

   protected:
    static bool OpenForInfo(const base::FilePath& path, base::File* file);
    static bool GetInfo(const base::File& file,
                        BY_HANDLE_FILE_INFORMATION* info);

    base::FilePath path_to_match_;
    base::File file_;
    BY_HANDLE_FILE_INFORMATION file_info_;

   private:
    DISALLOW_COPY_AND_ASSIGN(ProgramCompare);
  };  // class ProgramCompare

 private:
  DISALLOW_COPY_AND_ASSIGN(InstallUtil);
};


#endif  // CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_