• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
6 #define CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
7 
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 #include "base/basictypes.h"
13 #include "base/files/file_path.h"
14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/version.h"
18 #include "chrome/installer/util/browser_distribution.h"
19 #include "chrome/installer/util/product.h"
20 #include "chrome/installer/util/util_constants.h"
21 
22 #if defined(OS_WIN)
23 #include <windows.h>  // NOLINT
24 #endif
25 
26 namespace base {
27 class CommandLine;
28 }
29 
30 namespace installer {
31 
32 class ChannelInfo;
33 class InstallationState;
34 class MasterPreferences;
35 
36 class ProductState;
37 
38 typedef std::vector<Product*> Products;
39 
40 // Encapsulates the state of the current installation operation.  Only valid
41 // for installs and upgrades (not for uninstalls or non-install commands).
42 // This class interprets the command-line arguments and master preferences and
43 // determines the operations to be performed. For example, the Chrome Binaries
44 // are automatically added if required in multi-install mode.
45 // TODO(erikwright): This is now used a fair bit during uninstall, and
46 // InstallerState::Initialize() contains a lot of code for uninstall. The class
47 // comment should probably be updated.
48 // TODO(grt): Rename to InstallerEngine/Conductor or somesuch?
49 class InstallerState {
50  public:
51   enum Level {
52     UNKNOWN_LEVEL,
53     USER_LEVEL,
54     SYSTEM_LEVEL
55   };
56 
57   enum PackageType {
58     UNKNOWN_PACKAGE_TYPE,
59     SINGLE_PACKAGE,
60     MULTI_PACKAGE
61   };
62 
63   enum Operation {
64     UNINITIALIZED,
65     SINGLE_INSTALL_OR_UPDATE,
66     MULTI_INSTALL,
67     MULTI_UPDATE,
68     UNINSTALL
69   };
70 
71   // Constructs an uninitialized instance; see Initialize().
72   InstallerState();
73 
74   // Constructs an initialized but empty instance.
75   explicit InstallerState(Level level);
76 
77   // Initializes this object based on the current operation.
78   void Initialize(const base::CommandLine& command_line,
79                   const MasterPreferences& prefs,
80                   const InstallationState& machine_state);
81 
82   // Adds a product constructed on the basis of |state|, setting this object's
83   // msi flag if |state| is msi-installed.  Returns the product that was added,
84   // or NULL if |state| is incompatible with this object.  Ownership is not
85   // passed to the caller.
86   Product* AddProductFromState(BrowserDistribution::Type type,
87                                const ProductState& state);
88 
89   // Returns the product that was added, or NULL if |product| is incompatible
90   // with this object.  Ownership of |product| is taken by this object, while
91   // ownership of the return value is not passed to the caller.
92   Product* AddProduct(scoped_ptr<Product>* product);
93 
94   // Removes |product| from the set of products to be operated on.  The object
95   // pointed to by |product| is freed.  Returns false if |product| is not
96   // present in the set.
97   bool RemoveProduct(const Product* product);
98 
99   // The level (user or system) of this operation.
level()100   Level level() const { return level_; }
101 
102   // The package type (single or multi) of this operation.
package_type()103   PackageType package_type() const { return package_type_; }
104 
105   // An identifier of this operation.
operation()106   Operation operation() const { return operation_; }
107 
108   // A convenience method returning level() == SYSTEM_LEVEL.
109   // TODO(grt): Eradicate the bool in favor of the enum.
110   bool system_install() const;
111 
112   // A convenience method returning package_type() == MULTI_PACKAGE.
113   // TODO(grt): Eradicate the bool in favor of the enum.
114   bool is_multi_install() const;
115 
116   // A convenient method returning the presence of the
117   // --ensure-google-update-present switch.
ensure_google_update_present()118   bool ensure_google_update_present() const {
119     return ensure_google_update_present_;
120   }
121 
122   // The full path to the place where the operand resides.
target_path()123   const base::FilePath& target_path() const { return target_path_; }
124 
125   // True if the "msi" preference is set or if a product with the "msi" state
126   // flag is set is to be operated on.
is_msi()127   bool is_msi() const { return msi_; }
128 
129   // True if the --verbose-logging command-line flag is set or if the
130   // verbose_logging master preferences option is true.
verbose_logging()131   bool verbose_logging() const { return verbose_logging_; }
132 
133 #if defined(OS_WIN)
root_key()134   HKEY root_key() const { return root_key_; }
135 #endif
136 
137   // The ClientState key by which we interact with Google Update.
state_key()138   const std::wstring& state_key() const { return state_key_; }
139 
140   // Convenience method to return the type of the BrowserDistribution associated
141   // with the ClientState key we will be interacting with.
state_type()142   BrowserDistribution::Type state_type() const { return state_type_; }
143 
144   // Returns the BrowserDistribution instance corresponding to the binaries for
145   // this run if we're operating on a multi-package product.
multi_package_binaries_distribution()146   BrowserDistribution* multi_package_binaries_distribution() const {
147     DCHECK(package_type_ == MULTI_PACKAGE);
148     DCHECK(multi_package_distribution_ != NULL);
149     return multi_package_distribution_;
150   }
151 
products()152   const Products& products() const { return products_.get(); }
153 
154   // Returns the product of the desired type, or NULL if none found.
155   const Product* FindProduct(BrowserDistribution::Type distribution_type) const;
156 
157   // Returns the currently installed version in |target_path|, or NULL if no
158   // products are installed.  Ownership is passed to the caller.
159   base::Version* GetCurrentVersion(
160       const InstallationState& machine_state) const;
161 
162   // Returns the critical update version if all of the following are true:
163   // * --critical-update-version=CUV was specified on the command-line.
164   // * current_version == NULL or current_version < CUV.
165   // * new_version >= CUV.
166   // Otherwise, returns an invalid version.
167   base::Version DetermineCriticalVersion(
168       const base::Version* current_version,
169       const base::Version& new_version) const;
170 
171   // Returns whether or not there is currently a Chrome Frame instance running.
172   // Note that there isn't a mechanism to lock Chrome Frame in place, so Chrome
173   // Frame may either exit or start up after this is called.
174   bool IsChromeFrameRunning(const InstallationState& machine_state) const;
175 
176   // Returns true if any of the binaries from a multi-install Chrome Frame that
177   // has been migrated to single-install are still in use.
178   bool AreBinariesInUse(const InstallationState& machine_state) const;
179 
180   // Returns the path to the installer under Chrome version folder
181   // (for example <target_path>\Google\Chrome\Application\<Version>\Installer)
182   base::FilePath GetInstallerDirectory(const base::Version& version) const;
183 
184   // Try to delete all directories under |temp_path| whose versions are less
185   // than |new_version| and not equal to |existing_version|. |existing_version|
186   // may be NULL.
187   void RemoveOldVersionDirectories(const base::Version& new_version,
188                                    base::Version* existing_version,
189                                    const base::FilePath& temp_path) const;
190 
191   // Adds to |com_dll_list| the list of COM DLLs that are to be registered
192   // and/or unregistered. The list may be empty.
193   void AddComDllList(std::vector<base::FilePath>* com_dll_list) const;
194 
195   bool SetChannelFlags(bool set, ChannelInfo* channel_info) const;
196 
197   // See InstallUtil::UpdateInstallerStage.
198   void UpdateStage(installer::InstallerStage stage) const;
199 
200   // For a MULTI_INSTALL or MULTI_UPDATE operation, updates the Google Update
201   // "ap" values for all products being operated on.
202   void UpdateChannels() const;
203 
204   // Sets installer result information in the registry for consumption by Google
205   // Update.  The InstallerResult value is set to 0 (SUCCESS) or 1
206   // (FAILED_CUSTOM_ERROR) depending on whether |status| maps to success or not.
207   // |status| itself is written to the InstallerError value.
208   // |string_resource_id|, if non-zero, identifies a localized string written to
209   // the InstallerResultUIString value.  |launch_cmd|, if non-NULL and
210   // non-empty, is written to the InstallerSuccessLaunchCmdLine value.
211   void WriteInstallerResult(InstallStatus status,
212                             int string_resource_id,
213                             const std::wstring* launch_cmd) const;
214 
215   // Returns true if this install needs to register an Active Setup command.
216   bool RequiresActiveSetup() const;
217 
218  protected:
219   // Bits for the |file_bits| argument of AnyExistsAndIsInUse.
220   enum {
221     CHROME_DLL              = 1 << 0,
222     CHROME_FRAME_DLL        = 1 << 1,
223     CHROME_FRAME_HELPER_DLL = 1 << 2,
224     CHROME_FRAME_HELPER_EXE = 1 << 3,
225     NUM_BINARIES            = 4
226   };
227 
228   // Returns true if |file| exists and cannot be opened for exclusive write
229   // access.
230   static bool IsFileInUse(const base::FilePath& file);
231 
232   // Clears the instance to an uninitialized state.
233   void Clear();
234 
235   // Returns true if any file corresponding to a bit in |file_bits| (from the
236   // enum above) for the currently installed version exists and is in use.
237   bool AnyExistsAndIsInUse(const InstallationState& machine_state,
238                            uint32 file_bits) const;
239   base::FilePath GetDefaultProductInstallPath(BrowserDistribution* dist) const;
240   bool CanAddProduct(const Product& product,
241                      const base::FilePath* product_dir) const;
242   Product* AddProductInDirectory(const base::FilePath* product_dir,
243                                  scoped_ptr<Product>* product);
244   Product* AddProductFromPreferences(
245       BrowserDistribution::Type distribution_type,
246       const MasterPreferences& prefs,
247       const InstallationState& machine_state);
248   bool IsMultiInstallUpdate(const MasterPreferences& prefs,
249                             const InstallationState& machine_state);
250 
251   // Enumerates all files named one of
252   // [chrome.exe, old_chrome.exe, new_chrome.exe] in target_path_ and
253   // returns their version numbers in a set.
254   void GetExistingExeVersions(std::set<std::string>* existing_versions) const;
255 
256   // Sets this object's level and updates the root_key_ accordingly.
257   void set_level(Level level);
258 
259   // Sets this object's package type and updates the multi_package_distribution_
260   // accordingly.
261   void set_package_type(PackageType type);
262 
263   Operation operation_;
264   base::FilePath target_path_;
265   std::wstring state_key_;
266   BrowserDistribution::Type state_type_;
267   ScopedVector<Product> products_;
268   BrowserDistribution* multi_package_distribution_;
269   base::Version critical_update_version_;
270   Level level_;
271   PackageType package_type_;
272 #if defined(OS_WIN)
273   HKEY root_key_;
274 #endif
275   bool msi_;
276   bool verbose_logging_;
277   bool ensure_google_update_present_;
278 
279  private:
280   DISALLOW_COPY_AND_ASSIGN(InstallerState);
281 };  // class InstallerState
282 
283 }  // namespace installer
284 
285 #endif  // CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
286