diff options
author | pmonette <pmonette@chromium.org> | 2015-10-16 15:22:07 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-16 22:23:24 +0000 |
commit | 1568223f9d1a291c4800ef657c253dd96bb37fb0 (patch) | |
tree | 9cf4d70aed5e60fbb19a9e6e5b1a0c478c855387 /base | |
parent | 9a57f509d0fa6722bb29925a8adb73185e48b619 (diff) | |
download | chromium_src-1568223f9d1a291c4800ef657c253dd96bb37fb0.zip chromium_src-1568223f9d1a291c4800ef657c253dd96bb37fb0.tar.gz chromium_src-1568223f9d1a291c4800ef657c253dd96bb37fb0.tar.bz2 |
Reverted how taskbar pinning works.
The change was causing Chrome to chrash when pinning shortcuts because
because of third-party shell extensions (See bug).
Also removed the unused start menu pinning in Windows 10.
Previous CLs:
Changing pin to taskbar crrev.com/1193363003
Adding pin to start menu crrev.com/1242763002
BUG=540710
Review URL: https://codereview.chromium.org/1402003002
Cr-Commit-Position: refs/heads/master@{#354621}
Diffstat (limited to 'base')
-rw-r--r-- | base/base_paths_win.h | 2 | ||||
-rw-r--r-- | base/win/shortcut.cc | 138 | ||||
-rw-r--r-- | base/win/shortcut.h | 24 |
3 files changed, 23 insertions, 141 deletions
diff --git a/base/base_paths_win.h b/base/base_paths_win.h index 454d67b..d9dbc39 100644 --- a/base/base_paths_win.h +++ b/base/base_paths_win.h @@ -43,7 +43,7 @@ enum { // on all user's Desktop). DIR_USER_QUICK_LAUNCH, // Directory for the quick launch shortcuts. DIR_TASKBAR_PINS, // Directory for the shortcuts pinned to taskbar - // (Win7+) via base::win::PinShortcutToTaskbar(). + // (Win7-8) via base::win::PinShortcutToTaskbar(). DIR_WINDOWS_FONTS, // Usually C:\Windows\Fonts. PATH_WIN_END diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc index 2dd01a8..ccfa2f5 100644 --- a/base/win/shortcut.cc +++ b/base/win/shortcut.cc @@ -5,18 +5,13 @@ #include "base/win/shortcut.h" #include <shellapi.h> -#include <shldisp.h> #include <shlobj.h> #include <propkey.h> #include "base/files/file_util.h" -#include "base/strings/string_util.h" #include "base/threading/thread_restrictions.h" -#include "base/win/scoped_bstr.h" #include "base/win/scoped_comptr.h" -#include "base/win/scoped_handle.h" #include "base/win/scoped_propvariant.h" -#include "base/win/scoped_variant.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" @@ -25,92 +20,6 @@ namespace win { namespace { -// String resource IDs in shell32.dll. -const uint32_t kPinToTaskbarID = 5386; // Win7+ -const uint32_t kUnpinFromTaskbarID = 5387; // Win7+ -const uint32_t kPinToStartID = 51201; // Win8+ -const uint32_t kUnpinFromStartID = 51394; // Win10+ - -// Traits for a GenericScopedHandle that will free a module on closure. -struct ModuleTraits { - typedef HMODULE Handle; - static Handle NullHandle() { return nullptr; } - static bool IsHandleValid(Handle module) { return !!module; } - static bool CloseHandle(Handle module) { return !!::FreeLibrary(module); } - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(ModuleTraits); -}; - -// An object that will free a module when it goes out of scope. -using ScopedLibrary = GenericScopedHandle<ModuleTraits, DummyVerifierTraits>; - -// Returns the shell resource string identified by |resource_id|, or an empty -// string on error. -string16 LoadShellResourceString(uint32_t resource_id) { - ScopedLibrary shell32(::LoadLibrary(L"shell32.dll")); - if (!shell32.IsValid()) - return string16(); - - const wchar_t* resource_ptr = nullptr; - int length = ::LoadStringW(shell32.Get(), resource_id, - reinterpret_cast<wchar_t*>(&resource_ptr), 0); - if (!length || !resource_ptr) - return string16(); - return string16(resource_ptr, length); -} - -// Uses the shell to perform the verb identified by |resource_id| on |path|. -bool DoVerbOnFile(uint32_t resource_id, const FilePath& path) { - string16 verb_name(LoadShellResourceString(resource_id)); - if (verb_name.empty()) - return false; - - ScopedComPtr<IShellDispatch> shell_dispatch; - HRESULT hresult = - shell_dispatch.CreateInstance(CLSID_Shell, nullptr, CLSCTX_INPROC_SERVER); - if (FAILED(hresult) || !shell_dispatch.get()) - return false; - - ScopedComPtr<Folder> folder; - hresult = shell_dispatch->NameSpace( - ScopedVariant(path.DirName().value().c_str()), folder.Receive()); - if (FAILED(hresult) || !folder.get()) - return false; - - ScopedComPtr<FolderItem> item; - hresult = folder->ParseName(ScopedBstr(path.BaseName().value().c_str()), - item.Receive()); - if (FAILED(hresult) || !item.get()) - return false; - - ScopedComPtr<FolderItemVerbs> verbs; - hresult = item->Verbs(verbs.Receive()); - if (FAILED(hresult) || !verbs.get()) - return false; - - long verb_count = 0; - hresult = verbs->get_Count(&verb_count); - if (FAILED(hresult)) - return false; - - for (long i = 0; i < verb_count; ++i) { - ScopedComPtr<FolderItemVerb> verb; - hresult = verbs->Item(ScopedVariant(i, VT_I4), verb.Receive()); - if (FAILED(hresult) || !verb.get()) - continue; - ScopedBstr name; - hresult = verb->get_Name(name.Receive()); - if (FAILED(hresult)) - continue; - if (StringPiece16(name, name.Length()) == verb_name) { - hresult = verb->DoIt(); - return SUCCEEDED(hresult); - } - } - return false; -} - // Initializes |i_shell_link| and |i_persist_file| (releasing them first if they // are already initialized). // If |shortcut| is not NULL, loads |shortcut| into |i_persist_file|. @@ -405,49 +314,32 @@ bool ResolveShortcut(const FilePath& shortcut_path, return true; } +bool CanPinShortcutToTaskbar() { + // "Pin to taskbar" appeared in Windows 7 and stopped being supported in + // Windows 10. + return GetVersion() >= VERSION_WIN7 && GetVersion() < VERSION_WIN10; +} + bool PinShortcutToTaskbar(const FilePath& shortcut) { base::ThreadRestrictions::AssertIOAllowed(); + DCHECK(CanPinShortcutToTaskbar()); - // "Pin to taskbar" is only supported after Win7. - if (GetVersion() < VERSION_WIN7) - return false; - - return DoVerbOnFile(kPinToTaskbarID, shortcut); + intptr_t result = reinterpret_cast<intptr_t>(ShellExecute( + NULL, L"taskbarpin", shortcut.value().c_str(), NULL, NULL, 0)); + return result > 32; } bool UnpinShortcutFromTaskbar(const FilePath& shortcut) { base::ThreadRestrictions::AssertIOAllowed(); - // "Unpin from taskbar" is only supported after Win7. + // "Unpin from taskbar" is only supported after Win7. It is possible to remove + // a shortcut pinned by a user on Windows 10+. if (GetVersion() < VERSION_WIN7) return false; - return DoVerbOnFile(kUnpinFromTaskbarID, shortcut); -} - -bool PinShortcutToStart(const FilePath& shortcut) { - base::ThreadRestrictions::AssertIOAllowed(); - - // While "Pin to Start" is supported as of Win8, it was never used by Chrome - // in Win8. The behaviour on Win8 is different (new shortcut every time - // instead of a single pin associated with its app id) and the Start Menu - // shortcut itself is visible on the Start Screen whereas it is not on Win10. - // For simplicity's sake and per greater necessity on Win10, it is only - // supported in Chrome on Win10+. - if (GetVersion() < VERSION_WIN10) - return false; - - return DoVerbOnFile(kPinToStartID, shortcut); -} - -bool UnpinShortcutFromStart(const FilePath& shortcut) { - base::ThreadRestrictions::AssertIOAllowed(); - - // "Unpin from Start Menu" is only supported after Win10. - if (GetVersion() < VERSION_WIN10) - return false; - - return DoVerbOnFile(kUnpinFromStartID, shortcut); + intptr_t result = reinterpret_cast<intptr_t>(ShellExecute( + NULL, L"taskbarunpin", shortcut.value().c_str(), NULL, NULL, 0)); + return result > 32; } } // namespace win diff --git a/base/win/shortcut.h b/base/win/shortcut.h index 4ff2912a..a41cc3d 100644 --- a/base/win/shortcut.h +++ b/base/win/shortcut.h @@ -152,9 +152,13 @@ BASE_EXPORT bool ResolveShortcut(const FilePath& shortcut_path, FilePath* target_path, string16* args); -// Pins a shortcut to the Windows 7+ taskbar. The |shortcut| file must already -// exist and be a shortcut that points to an executable. The app id of the -// shortcut is used to group windows and must be set correctly. +// Pin to taskbar is only supported on Windows 7 and Windows 8. Returns true on +// those platforms. +BASE_EXPORT bool CanPinShortcutToTaskbar(); + +// Pins a shortcut to the taskbar on Windows 7 and 8. The |shortcut| file must +// already exist and be a shortcut that points to an executable. The app id of +// the shortcut is used to group windows and must be set correctly. BASE_EXPORT bool PinShortcutToTaskbar(const FilePath& shortcut); // Unpins a shortcut from the Windows 7+ taskbar. The |shortcut| must exist and @@ -162,20 +166,6 @@ BASE_EXPORT bool PinShortcutToTaskbar(const FilePath& shortcut); // identifier for the taskbar item to remove and must be set correctly. BASE_EXPORT bool UnpinShortcutFromTaskbar(const FilePath& shortcut); -// Pins a shortcut to the Windows 10+ start menu. The |shortcut| file must -// already exist and be a shortcut that points to an executable. The app id of -// the shortcut is used as an identifier by the shell to know that all shortcuts -// with this app id point to this pin (i.e. "Unpin" instead of "Pin" in those -// shortcuts' context menus). Unpinning is unecessary on uninstall as Windows -// handles getting rid of stale Start pins. -BASE_EXPORT bool PinShortcutToStart(const FilePath& shortcut); - -// Unpins a shortcut from the Windows 10+ start menu. The |shortcut| must exist -// and already be pinned to the start menu. The app id of the shortcut is used -// as the identifier for the start menu item to remove and must be set -// correctly. -BASE_EXPORT bool UnpinShortcutFromStart(const FilePath& shortcut); - } // namespace win } // namespace base |