15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file declares utility functions for the installer. The original reason 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for putting these functions in installer\util library is so that we can 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// separate out the critical logic and write unit tests for it. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <tchar.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/file.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/browser_distribution.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/util_constants.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WorkItemList; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace base { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class Version; 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a utility class that provides common installation related 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// utility methods that can be used by installer and also unit tested 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// independently. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InstallUtil { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the path to this distribution's Active Setup registry entries. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // e.g. Software\Microsoft\Active Setup\Installed Components\<dist_guid> 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static base::string16 GetActiveSetupPath(BrowserDistribution* dist); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Attempts to trigger the command that would be run by Active Setup for a 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // system-level Chrome. For use only when system-level Chrome is installed. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void TriggerActiveSetupCommand(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Launches given exe as admin on Vista. 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static bool ExecuteExeAsAdmin(const base::CommandLine& cmd, DWORD* exit_code); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads the uninstall command for Chromium from registry and returns it. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If system_install is true the command is read from HKLM, otherwise 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from HKCU. 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static base::CommandLine GetChromeUninstallCmd( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool system_install, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type distribution_type); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the version of Chrome installed on the system by checking the 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Google Update registry key. Fills |version| with the version or a 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default-constructed Version if no version is found. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system_install: if true, looks for version number under the HKLM root, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise looks under the HKCU. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void GetChromeVersion(BrowserDistribution* dist, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool system_install, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Version* version); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the last critical update (version) of Chrome. Fills |version| with the 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // version or a default-constructed Version if no version is found. A critical 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // update is a specially flagged version (by Google Update) that contains an 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // important security fix. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system_install: if true, looks for version number under the HKLM root, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise looks under the HKCU. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void GetCriticalUpdateVersion(BrowserDistribution* dist, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool system_install, 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Version* version); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function checks if the current OS is supported for Chromium. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsOSSupported(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds work items to |install_list|, which should be a 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NoRollbackWorkItemList, to set installer error information in the registry 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for consumption by Google Update. |state_key| must be the full path to an 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // app's ClientState key. See InstallerState::WriteInstallerResult for more 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // details. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void AddInstallerResultItems(bool system_install, 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& state_key, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::InstallStatus status, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int string_resource_id, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16* const launch_cmd, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkItemList* install_list); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the installer stage reported by Google Update. |state_key_path| 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be obtained via the state_key method of an InstallerState instance 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // created before the machine state is modified by the installer. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void UpdateInstallerStage(bool system_install, 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& state_key_path, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::InstallerStage stage); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this installation path is per user, otherwise returns 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false (per machine install, meaning: the exe_path contains path to 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Program Files). 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsPerUserInstall(const wchar_t* const exe_path); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the installation represented by the pair of |dist| and 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |system_level| is a multi install. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsMultiInstall(BrowserDistribution* dist, bool system_install); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this is running setup process for Chrome SxS (as 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicated by the presence of --chrome-sxs on the command line) or if this 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is running Chrome process from the Chrome SxS installation (as indicated 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by either --chrome-sxs or the executable path). 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool IsChromeSxSProcess(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Returns true if the sentinel file exists (or the path cannot be obtained). 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch static bool IsFirstRunSentinelPresent(); 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Populates |path| with EULA sentinel file path. Returns false on error. 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static bool GetEULASentinelFilePath(base::FilePath* path); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the registry key at path key_path under the key given by root_key. 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static bool DeleteRegistryKey(HKEY root_key, 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::string16& key_path, 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) REGSAM wow64_access); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the registry value named value_name at path key_path under the key 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // given by reg_root. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static bool DeleteRegistryValue(HKEY reg_root, const base::string16& key_path, 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) REGSAM wow64_access, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& value_name); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An interface to a predicate function for use by DeleteRegistryKeyIf and 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DeleteRegistryValueIf. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class RegistryValuePredicate { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~RegistryValuePredicate() { } 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool Evaluate(const base::string16& value) const = 0; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The result of a conditional delete operation (i.e., DeleteFOOIf). 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ConditionalDeleteResult { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOT_FOUND, // The condition was not satisfied. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DELETED, // The condition was satisfied and the delete succeeded. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DELETE_FAILED // The condition was satisfied but the delete failed. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the key |key_to_delete_path| under |root_key| iff the value 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |value_name| in the key |key_to_test_path| under |root_key| satisfies 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |predicate|. |value_name| may be either NULL or an empty string to test 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the key's default value. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ConditionalDeleteResult DeleteRegistryKeyIf( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HKEY root_key, 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& key_to_delete_path, 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& key_to_test_path, 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) REGSAM wow64_access, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* value_name, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RegistryValuePredicate& predicate); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deletes the value |value_name| in the key |key_path| under |root_key| iff 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its current value satisfies |predicate|. |value_name| may be either NULL 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or an empty string to test/delete the key's default value. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ConditionalDeleteResult DeleteRegistryValueIf( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HKEY root_key, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* key_path, 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) REGSAM wow64_access, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* value_name, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RegistryValuePredicate& predicate); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A predicate that performs a case-sensitive string comparison. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ValueEquals : public RegistryValuePredicate { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit ValueEquals(const base::string16& value_to_match) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : value_to_match_(value_to_match) { } 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool Evaluate(const base::string16& value) const OVERRIDE; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 value_to_match_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ValueEquals); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns zero on install success, or an InstallStatus value otherwise. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int GetInstallReturnCode(installer::InstallStatus install_status); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Composes |program| and |arguments| into |command_line|. 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void MakeUninstallCommand(const base::string16& program, 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16& arguments, 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::CommandLine* command_line); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a string in the form YYYYMMDD of the current date. 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static base::string16 GetCurrentDate(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A predicate that compares the program portion of a command line with a 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // given file path. First, the file paths are compared directly. If they do 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not match, the filesystem is consulted to determine if the paths reference 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same file. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ProgramCompare : public RegistryValuePredicate { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit ProgramCompare(const base::FilePath& path_to_match); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ProgramCompare(); 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool Evaluate(const base::string16& value) const OVERRIDE; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool EvaluatePath(const base::FilePath& path) const; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static bool OpenForInfo(const base::FilePath& path, base::File* file); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static bool GetInfo(const base::File& file, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BY_HANDLE_FILE_INFORMATION* info); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path_to_match_; 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::File file_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BY_HANDLE_FILE_INFORMATION file_info_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ProgramCompare); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; // class ProgramCompare 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(InstallUtil); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_INSTALLER_UTIL_INSTALL_UTIL_H_ 216