Commit ee566a63 authored by Veranika Liaukevich's avatar Veranika Liaukevich Committed by Commit Bot

Profile reset: ensure that all Chrome shortcuts are user-visible

Remove all unexpected attributes from shortcuts pointing to the current Chrome binary.

Bug: 970253
Change-Id: Idfaf5cadfd8e3641f8c6593fb0f0796dce981e2b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2410922
Commit-Queue: Veranika Liaukevich <veranika@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarXinghui Lu <xinghuilu@chromium.org>
Reviewed-by: default avatarDaniel Rubery <drubery@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807974}
parent ce5ff21b
......@@ -69,6 +69,9 @@ void ResetShortcutsOnBlockingThread() {
ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
static_cast<ShellUtil::ShortcutLocation>(location),
ShellUtil::CURRENT_USER, chrome_exe, true, nullptr, nullptr);
ShellUtil::ResetShortcutFileAttributes(
static_cast<ShellUtil::ShortcutLocation>(location),
ShellUtil::CURRENT_USER, chrome_exe);
}
}
......
......@@ -237,6 +237,8 @@ class ShortcutHandler {
const base::string16& args);
void CheckShortcutHasArguments(const base::string16& desired_args) const;
void Delete();
void HideFile();
bool IsFileHidden() const;
private:
#if defined(OS_WIN)
......@@ -293,6 +295,20 @@ void ShortcutHandler::Delete() {
EXPECT_TRUE(base::DeleteFile(shortcut_path_));
shortcut_path_.clear();
}
void ShortcutHandler::HideFile() {
DWORD attributes = ::GetFileAttributes(shortcut_path_.value().c_str());
ASSERT_NE(attributes, INVALID_FILE_ATTRIBUTES);
ASSERT_TRUE(::SetFileAttributes(shortcut_path_.value().c_str(),
attributes | FILE_ATTRIBUTE_HIDDEN));
}
bool ShortcutHandler::IsFileHidden() const {
DWORD attributes = ::GetFileAttributes(shortcut_path_.value().c_str());
EXPECT_NE(attributes, INVALID_FILE_ATTRIBUTES);
return attributes & FILE_ATTRIBUTE_HIDDEN;
}
#else
ShortcutHandler::ShortcutHandler() {}
......@@ -315,6 +331,12 @@ void ShortcutHandler::CheckShortcutHasArguments(
void ShortcutHandler::Delete() {
}
void ShortcutHandler::HideFile() {}
bool ShortcutHandler::IsFileHidden() const {
return false;
}
#endif // defined(OS_WIN)
// MockInstantService
......@@ -729,13 +751,18 @@ TEST_F(ProfileResetterTest, ResetShortcuts) {
ShortcutCommand command_line = shortcut.CreateWithArguments(
base::ASCIIToUTF16("chrome.lnk"),
base::ASCIIToUTF16("--profile-directory=Default foo.com"));
shortcut.HideFile();
shortcut.CheckShortcutHasArguments(base::ASCIIToUTF16(
"--profile-directory=Default foo.com"));
#if defined(OS_WIN)
ASSERT_TRUE(shortcut.IsFileHidden());
#endif
ResetAndWait(ProfileResetter::SHORTCUTS);
shortcut.CheckShortcutHasArguments(base::ASCIIToUTF16(
"--profile-directory=Default"));
EXPECT_FALSE(shortcut.IsFileHidden());
}
TEST_F(ProfileResetterTest, ResetFewFlags) {
......
......@@ -12,6 +12,7 @@
#include <objbase.h>
#include <shlobj.h>
#include <shobjidl.h>
#include <windows.h>
#include <wrl/client.h>
#include <algorithm>
......@@ -1405,6 +1406,18 @@ bool ShortcutOpListOrRemoveUnknownArgs(
shortcut_path, updated_properties, base::win::SHORTCUT_UPDATE_EXISTING);
}
bool ShortcutOpResetAttributes(const base::FilePath& file_path) {
const DWORD kAllowedAttributes =
FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_REPARSE_POINT;
DWORD attributes = ::GetFileAttributes(file_path.value().c_str());
if (attributes == INVALID_FILE_ATTRIBUTES)
return false;
if ((attributes & (~kAllowedAttributes)) == 0)
return true;
return ::SetFileAttributes(file_path.value().c_str(),
attributes & kAllowedAttributes);
}
// {|location|, |level|} determine |shortcut_folder|.
// For each shortcut in |shortcut_folder| that match |shortcut_filter|, apply
// |shortcut_operation|. Returns true if all operations are successful.
......@@ -2365,6 +2378,19 @@ bool ShellUtil::ShortcutListMaybeRemoveUnknownArgs(
shortcut_operation, location, level, cancel);
}
// static
bool ShellUtil::ResetShortcutFileAttributes(ShortcutLocation location,
ShellChange level,
const base::FilePath& chrome_exe) {
if (!ShortcutLocationIsSupported(location))
return false;
FilterTargetEq shortcut_filter(chrome_exe, /*require_args=*/false);
ShortcutOperationCallback shortcut_operation =
base::BindRepeating(&ShortcutOpResetAttributes);
return BatchShortcutAction(shortcut_filter.AsShortcutFilterCallback(),
shortcut_operation, location, level, nullptr);
}
bool ShellUtil::GetUserSpecificRegistrySuffix(base::string16* suffix) {
// Use a thread-safe cache for the user's suffix.
static base::LazyInstance<UserSpecificRegistrySuffix>::Leaky suffix_instance =
......
......@@ -593,6 +593,14 @@ class ShellUtil {
const scoped_refptr<SharedCancellationFlag>& cancel,
std::vector<std::pair<base::FilePath, base::string16>>* shortcuts);
// Resets file attributes on shortcuts to a known good default value.
// Ensures that Chrome shortcuts are not hidden from the user.
// Returns true if all updates to matching shortcuts are successful or if no
// matching shortcuts were found.
static bool ResetShortcutFileAttributes(ShortcutLocation location,
ShellChange level,
const base::FilePath& chrome_exe);
// Sets |suffix| to the base 32 encoding of the md5 hash of this user's sid
// preceded by a dot.
// This is guaranteed to be unique on the machine and 27 characters long
......
......@@ -706,6 +706,40 @@ TEST_F(ShellUtilShortcutTest, ClearShortcutArguments) {
expected_properties4);
}
TEST_F(ShellUtilShortcutTest, ShortcutsAreNotHidden) {
// Shortcut 1: targets "chrome.exe"; not hidden.
test_properties_.set_shortcut_name(L"Chrome Visible");
ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, test_properties_,
ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
base::FilePath visible_shortcut = GetExpectedShortcutPath(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, test_properties_);
ASSERT_TRUE(base::PathExists(visible_shortcut));
// Shortcut 2: targets "chrome.exe"; hidden.
test_properties_.set_shortcut_name(L"Chrome Hidden");
ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, test_properties_,
ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS));
base::FilePath hidden_shortcut = GetExpectedShortcutPath(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, test_properties_);
ASSERT_TRUE(base::PathExists(hidden_shortcut));
DWORD shortcut_attributes =
::GetFileAttributes(hidden_shortcut.value().c_str());
ASSERT_NE(shortcut_attributes, INVALID_FILE_ATTRIBUTES);
ASSERT_TRUE(::SetFileAttributes(hidden_shortcut.value().c_str(),
shortcut_attributes | FILE_ATTRIBUTE_HIDDEN));
EXPECT_TRUE(ShellUtil::ResetShortcutFileAttributes(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, ShellUtil::CURRENT_USER,
chrome_exe_));
shortcut_attributes = ::GetFileAttributes(visible_shortcut.value().c_str());
EXPECT_EQ(shortcut_attributes & FILE_ATTRIBUTE_HIDDEN, 0UL);
shortcut_attributes = ::GetFileAttributes(hidden_shortcut.value().c_str());
EXPECT_EQ(shortcut_attributes & FILE_ATTRIBUTE_HIDDEN, 0UL);
}
TEST_F(ShellUtilShortcutTest, CreateMultipleStartMenuShortcutsAndRemoveFolder) {
ASSERT_TRUE(ShellUtil::CreateOrUpdateShortcut(
ShellUtil::SHORTCUT_LOCATION_START_MENU_CHROME_DIR_DEPRECATED,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment