summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util
diff options
context:
space:
mode:
authorgab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-31 19:25:35 +0000
committergab@chromium.org <gab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-31 19:25:35 +0000
commit0b8f24ee0f797709bc74370289c8717d4ad260ec (patch)
tree9fd87ef38905db244689b6880f0132191483733a /chrome/installer/util
parent72b88641d0b1f10147600f66b3d24a681211cb3e (diff)
downloadchromium_src-0b8f24ee0f797709bc74370289c8717d4ad260ec.zip
chromium_src-0b8f24ee0f797709bc74370289c8717d4ad260ec.tar.gz
chromium_src-0b8f24ee0f797709bc74370289c8717d4ad260ec.tar.bz2
Move ProgramCompare from setup_util to install_util.
...and switch to oh so ever beautiful string16s. BUG=None TEST=setup_util_unittests installer_util_unittests --gtest_filter=InstallUtilTest.ProgramCompare Review URL: https://chromiumcodereview.appspot.com/10446095 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139837 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/util')
-rw-r--r--chrome/installer/util/install_util.cc106
-rw-r--r--chrome/installer/util/install_util.h57
-rw-r--r--chrome/installer/util/install_util_unittest.cc48
3 files changed, 176 insertions, 35 deletions
diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc
index 5f4e238..d61c0b9 100644
--- a/chrome/installer/util/install_util.cc
+++ b/chrome/installer/util/install_util.cc
@@ -179,7 +179,7 @@ Version* InstallUtil::GetChromeVersion(BrowserDistribution* dist,
LONG result = key.Open(reg_root, dist->GetVersionKey().c_str(),
KEY_QUERY_VALUE);
- std::wstring version_str;
+ string16 version_str;
if (result == ERROR_SUCCESS)
result = key.ReadValue(google_update::kRegVersionField, &version_str);
@@ -235,10 +235,10 @@ bool InstallUtil::IsOSSupported() {
}
void InstallUtil::AddInstallerResultItems(bool system_install,
- const std::wstring& state_key,
+ const string16& state_key,
installer::InstallStatus status,
int string_resource_id,
- const std::wstring* const launch_cmd,
+ const string16* const launch_cmd,
WorkItemList* install_list) {
DCHECK(install_list);
const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
@@ -251,7 +251,7 @@ void InstallUtil::AddInstallerResultItems(bool system_install,
installer::kInstallerError,
static_cast<DWORD>(status), true);
if (string_resource_id != 0) {
- std::wstring msg = installer::GetLocalizedString(string_resource_id);
+ string16 msg = installer::GetLocalizedString(string_resource_id);
install_list->AddSetRegValueWorkItem(root, state_key,
installer::kInstallerResultUIString, msg, true);
}
@@ -262,7 +262,7 @@ void InstallUtil::AddInstallerResultItems(bool system_install,
}
void InstallUtil::UpdateInstallerStage(bool system_install,
- const std::wstring& state_key_path,
+ const string16& state_key_path,
installer::InstallerStage stage) {
DCHECK_LE(static_cast<installer::InstallerStage>(0), stage);
DCHECK_GT(installer::NUM_STAGES, stage);
@@ -328,7 +328,7 @@ bool CheckIsChromeSxSProcess() {
// Also return true if we are running from Chrome SxS installed path.
FilePath exe_dir;
PathService::Get(base::DIR_EXE, &exe_dir);
- std::wstring chrome_sxs_dir(installer::kGoogleChromeInstallSubDir2);
+ string16 chrome_sxs_dir(installer::kGoogleChromeInstallSubDir2);
chrome_sxs_dir.append(installer::kSxSSuffix);
return FilePath::CompareEqualIgnoreCase(exe_dir.BaseName().value(),
installer::kInstallBinaryDir) &&
@@ -363,7 +363,7 @@ bool InstallUtil::HasDelegateExecuteHandler(BrowserDistribution* dist,
// in case of failure. It returns true if deletion is successful,
// otherwise false.
bool InstallUtil::DeleteRegistryKey(HKEY root_key,
- const std::wstring& key_path) {
+ const string16& key_path) {
VLOG(1) << "Deleting registry key " << key_path;
LONG result = ::SHDeleteKey(root_key, key_path.c_str());
if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
@@ -378,8 +378,8 @@ bool InstallUtil::DeleteRegistryKey(HKEY root_key,
// in case of failure. It returns true if deletion is successful,
// otherwise false.
bool InstallUtil::DeleteRegistryValue(HKEY reg_root,
- const std::wstring& key_path,
- const std::wstring& value_name) {
+ const string16& key_path,
+ const string16& value_name) {
RegKey key(reg_root, key_path.c_str(), KEY_ALL_ACCESS);
VLOG(1) << "Deleting registry value " << value_name;
if (key.HasValue(value_name.c_str())) {
@@ -396,15 +396,15 @@ bool InstallUtil::DeleteRegistryValue(HKEY reg_root,
// static
InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryKeyIf(
HKEY root_key,
- const std::wstring& key_to_delete_path,
- const std::wstring& key_to_test_path,
+ const string16& key_to_delete_path,
+ const string16& key_to_test_path,
const wchar_t* value_name,
const RegistryValuePredicate& predicate) {
DCHECK(root_key);
DCHECK(value_name);
ConditionalDeleteResult delete_result = NOT_FOUND;
RegKey key;
- std::wstring actual_value;
+ string16 actual_value;
if (key.Open(root_key, key_to_test_path.c_str(),
KEY_QUERY_VALUE) == ERROR_SUCCESS &&
key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS &&
@@ -427,7 +427,7 @@ InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf(
DCHECK(value_name);
ConditionalDeleteResult delete_result = NOT_FOUND;
RegKey key;
- std::wstring actual_value;
+ string16 actual_value;
if (key.Open(root_key, key_path,
KEY_QUERY_VALUE | KEY_SET_VALUE) == ERROR_SUCCESS &&
key.ReadValue(value_name, &actual_value) == ERROR_SUCCESS &&
@@ -443,7 +443,7 @@ InstallUtil::ConditionalDeleteResult InstallUtil::DeleteRegistryValueIf(
return delete_result;
}
-bool InstallUtil::ValueEquals::Evaluate(const std::wstring& value) const {
+bool InstallUtil::ValueEquals::Evaluate(const string16& value) const {
return value == value_to_match_;
}
@@ -461,13 +461,13 @@ int InstallUtil::GetInstallReturnCode(installer::InstallStatus status) {
}
// static
-void InstallUtil::MakeUninstallCommand(const std::wstring& program,
- const std::wstring& arguments,
+void InstallUtil::MakeUninstallCommand(const string16& program,
+ const string16& arguments,
CommandLine* command_line) {
*command_line = CommandLine::FromString(L"\"" + program + L"\" " + arguments);
}
-std::wstring InstallUtil::GetCurrentDate() {
+string16 InstallUtil::GetCurrentDate() {
static const wchar_t kDateFormat[] = L"yyyyMMdd";
wchar_t date_str[arraysize(kDateFormat)] = {0};
int len = GetDateFormatW(LOCALE_INVARIANT, 0, NULL, kDateFormat,
@@ -478,5 +478,75 @@ std::wstring InstallUtil::GetCurrentDate() {
PLOG(DFATAL) << "GetDateFormat";
}
- return std::wstring(date_str, len);
+ return string16(date_str, len);
+}
+
+// Open |path| with minimal access to obtain information about it, returning
+// true and populating |handle| on success.
+// static
+bool InstallUtil::ProgramCompare::OpenForInfo(const FilePath& path,
+ base::win::ScopedHandle* handle) {
+ DCHECK(handle);
+ handle->Set(base::CreatePlatformFile(path, base::PLATFORM_FILE_OPEN, NULL,
+ NULL));
+ return handle->IsValid();
+}
+
+// Populate |info| for |handle|, returning true on success.
+// static
+bool InstallUtil::ProgramCompare::GetInfo(const base::win::ScopedHandle& handle,
+ BY_HANDLE_FILE_INFORMATION* info) {
+ DCHECK(handle.IsValid());
+ return GetFileInformationByHandle(
+ const_cast<base::win::ScopedHandle&>(handle), info) != 0;
+}
+
+InstallUtil::ProgramCompare::ProgramCompare(const FilePath& path_to_match)
+ : path_to_match_(path_to_match),
+ file_handle_(base::kInvalidPlatformFileValue),
+ file_info_() {
+ DCHECK(!path_to_match_.empty());
+ if (!OpenForInfo(path_to_match_, &file_handle_)) {
+ PLOG(WARNING) << "Failed opening " << path_to_match_.value()
+ << "; falling back to path string comparisons.";
+ } else if (!GetInfo(file_handle_, &file_info_)) {
+ PLOG(WARNING) << "Failed getting information for "
+ << path_to_match_.value()
+ << "; falling back to path string comparisons.";
+ file_handle_.Close();
+ }
+}
+
+InstallUtil::ProgramCompare::~ProgramCompare() {
+}
+
+bool InstallUtil::ProgramCompare::Evaluate(const string16& value) const {
+ // Suss out the exe portion of the value, which is expected to be a command
+ // line kinda (or exactly) like:
+ // "c:\foo\bar\chrome.exe" -- "%1"
+ FilePath program(CommandLine::FromString(value).GetProgram());
+ if (program.empty()) {
+ LOG(WARNING) << "Failed to parse an executable name from command line: \""
+ << value << "\"";
+ return false;
+ }
+
+ // Try the simple thing first: do the paths happen to match?
+ if (FilePath::CompareEqualIgnoreCase(path_to_match_.value(), program.value()))
+ return true;
+
+ // If the paths don't match and we couldn't open the expected file, we've done
+ // our best.
+ if (!file_handle_.IsValid())
+ return false;
+
+ // Open the program and see if it references the expected file.
+ base::win::ScopedHandle handle;
+ BY_HANDLE_FILE_INFORMATION info = {};
+
+ return (OpenForInfo(program, &handle) &&
+ GetInfo(handle, &info) &&
+ info.dwVolumeSerialNumber == file_info_.dwVolumeSerialNumber &&
+ info.nFileIndexHigh == file_info_.nFileIndexHigh &&
+ info.nFileIndexLow == file_info_.nFileIndexLow);
}
diff --git a/chrome/installer/util/install_util.h b/chrome/installer/util/install_util.h
index 5c4cb26..682290f 100644
--- a/chrome/installer/util/install_util.h
+++ b/chrome/installer/util/install_util.h
@@ -12,10 +12,11 @@
#include <tchar.h>
#include <windows.h>
-#include <string>
#include "base/basictypes.h"
#include "base/command_line.h"
+#include "base/string16.h"
+#include "base/win/scoped_handle.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/util_constants.h"
@@ -62,17 +63,17 @@ class InstallUtil {
// app's ClientState key. See InstallerState::WriteInstallerResult for more
// details.
static void AddInstallerResultItems(bool system_install,
- const std::wstring& state_key,
+ const string16& state_key,
installer::InstallStatus status,
int string_resource_id,
- const std::wstring* const launch_cmd,
+ const 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 std::wstring& state_key_path,
+ const string16& state_key_path,
installer::InstallerStage stage);
// Returns true if this installation path is per user, otherwise returns
@@ -96,19 +97,19 @@ class InstallUtil {
const string16& chrome_exe);
// Deletes the registry key at path key_path under the key given by root_key.
- static bool DeleteRegistryKey(HKEY root_key, const std::wstring& key_path);
+ static bool DeleteRegistryKey(HKEY root_key, const 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 std::wstring& key_path,
- const std::wstring& value_name);
+ static bool DeleteRegistryValue(HKEY reg_root, const string16& key_path,
+ const string16& value_name);
// An interface to a predicate function for use by DeleteRegistryKeyIf and
// DeleteRegistryValueIf.
class RegistryValuePredicate {
public:
virtual ~RegistryValuePredicate() { }
- virtual bool Evaluate(const std::wstring& value) const = 0;
+ virtual bool Evaluate(const string16& value) const = 0;
};
// The result of a conditional delete operation (i.e., DeleteFOOIf).
@@ -124,8 +125,8 @@ class InstallUtil {
// default value.
static ConditionalDeleteResult DeleteRegistryKeyIf(
HKEY root_key,
- const std::wstring& key_to_delete_path,
- const std::wstring& key_to_test_path,
+ const string16& key_to_delete_path,
+ const string16& key_to_test_path,
const wchar_t* value_name,
const RegistryValuePredicate& predicate);
@@ -141,11 +142,11 @@ class InstallUtil {
// A predicate that performs a case-sensitive string comparison.
class ValueEquals : public RegistryValuePredicate {
public:
- explicit ValueEquals(const std::wstring& value_to_match)
+ explicit ValueEquals(const string16& value_to_match)
: value_to_match_(value_to_match) { }
- virtual bool Evaluate(const std::wstring& value) const OVERRIDE;
+ virtual bool Evaluate(const string16& value) const OVERRIDE;
protected:
- std::wstring value_to_match_;
+ string16 value_to_match_;
private:
DISALLOW_COPY_AND_ASSIGN(ValueEquals);
};
@@ -154,12 +155,36 @@ class InstallUtil {
static int GetInstallReturnCode(installer::InstallStatus install_status);
// Composes |program| and |arguments| into |command_line|.
- static void MakeUninstallCommand(const std::wstring& program,
- const std::wstring& arguments,
+ static void MakeUninstallCommand(const string16& program,
+ const string16& arguments,
CommandLine* command_line);
// Returns a string in the form YYYYMMDD of the current date.
- static std::wstring GetCurrentDate();
+ static 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 FilePath& path_to_match);
+ virtual ~ProgramCompare();
+ virtual bool Evaluate(const string16& value) const OVERRIDE;
+
+ protected:
+ static bool OpenForInfo(const FilePath& path,
+ base::win::ScopedHandle* handle);
+ static bool GetInfo(const base::win::ScopedHandle& handle,
+ BY_HANDLE_FILE_INFORMATION* info);
+
+ FilePath path_to_match_;
+ base::win::ScopedHandle file_handle_;
+ BY_HANDLE_FILE_INFORMATION file_info_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProgramCompare);
+ }; // class ProgramCompare
private:
DISALLOW_COPY_AND_ASSIGN(InstallUtil);
diff --git a/chrome/installer/util/install_util_unittest.cc b/chrome/installer/util/install_util_unittest.cc
index ef0c39b..89c870d 100644
--- a/chrome/installer/util/install_util_unittest.cc
+++ b/chrome/installer/util/install_util_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -6,6 +6,7 @@
#include <utility>
#include "base/command_line.h"
+#include "base/string_util.h"
#include "base/test/test_reg_util_win.h"
#include "base/win/registry.h"
#include "chrome/installer/util/google_update_constants.h"
@@ -356,3 +357,48 @@ TEST_F(InstallUtilTest, ValueEquals) {
EXPECT_FALSE(pred.Evaluate(L"!howdy"));
EXPECT_TRUE(pred.Evaluate(L"howdy"));
}
+
+TEST_F(InstallUtilTest, ProgramCompare) {
+ FilePath some_long_dir(test_dir_.path().Append(L"Some Long Directory Name"));
+ FilePath expect(some_long_dir.Append(L"file.txt"));
+ FilePath expect_upcase(some_long_dir.Append(L"FILE.txt"));
+ FilePath other(some_long_dir.Append(L"otherfile.txt"));
+
+ // Tests where the expected file doesn't exist.
+
+ // Paths don't match.
+ EXPECT_FALSE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + other.value() + L"\""));
+ // Paths match exactly.
+ EXPECT_TRUE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + expect.value() + L"\""));
+ // Paths differ by case.
+ EXPECT_TRUE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + expect_upcase.value() + L"\""));
+
+ // Tests where the expected file exists.
+ static const char data[] = "data";
+ ASSERT_TRUE(file_util::CreateDirectory(some_long_dir));
+ ASSERT_NE(-1, file_util::WriteFile(expect, data, arraysize(data) - 1));
+ // Paths don't match.
+ EXPECT_FALSE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + other.value() + L"\""));
+ // Paths match exactly.
+ EXPECT_TRUE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + expect.value() + L"\""));
+ // Paths differ by case.
+ EXPECT_TRUE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + expect_upcase.value() + L"\""));
+
+ // Test where strings don't match, but the same file is indicated.
+ std::wstring short_expect;
+ DWORD short_len = GetShortPathName(expect.value().c_str(),
+ WriteInto(&short_expect, MAX_PATH),
+ MAX_PATH);
+ ASSERT_NE(static_cast<DWORD>(0), short_len);
+ ASSERT_GT(static_cast<DWORD>(MAX_PATH), short_len);
+ short_expect.resize(short_len);
+ ASSERT_FALSE(FilePath::CompareEqualIgnoreCase(expect.value(), short_expect));
+ EXPECT_TRUE(InstallUtil::ProgramCompare(expect).Evaluate(
+ L"\"" + short_expect + L"\""));
+}