Home | History | Annotate | Download | only in util
      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