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