Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2713)

Unified Diff: base/win/shortcut.cc

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/win/shortcut.h ('k') | base/win/win_util.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/win/shortcut.cc
diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc
index f8b2182b28664224c76ff39321dfcd6d326d5275..57f8e615d1dc5609062fc4a9e84460b434afcfea 100644
--- a/base/win/shortcut.cc
+++ b/base/win/shortcut.cc
@@ -5,13 +5,18 @@
#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"
@@ -20,6 +25,90 @@ namespace win {
namespace {
+// String resource IDs in shell32.dll.
+const uint32_t kPinToTaskbarID = 5386;
+const uint32_t kUnpinFromTaskbarID = 5387;
+
+// 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|.
@@ -314,28 +403,24 @@ bool ResolveShortcut(const FilePath& shortcut_path,
return true;
}
-bool TaskbarPinShortcutLink(const wchar_t* shortcut) {
+bool TaskbarPinShortcutLink(const FilePath& shortcut) {
base::ThreadRestrictions::AssertIOAllowed();
// "Pin to taskbar" is only supported after Win7.
if (GetVersion() < VERSION_WIN7)
return false;
- intptr_t result = reinterpret_cast<intptr_t>(
- ShellExecute(NULL, L"taskbarpin", shortcut, NULL, NULL, 0));
- return result > 32;
+ return DoVerbOnFile(kPinToTaskbarID, shortcut);
}
-bool TaskbarUnpinShortcutLink(const wchar_t* shortcut) {
+bool TaskbarUnpinShortcutLink(const FilePath& shortcut) {
base::ThreadRestrictions::AssertIOAllowed();
// "Unpin from taskbar" is only supported after Win7.
if (GetVersion() < VERSION_WIN7)
return false;
- intptr_t result = reinterpret_cast<intptr_t>(
- ShellExecute(NULL, L"taskbarunpin", shortcut, NULL, NULL, 0));
- return result > 32;
+ return DoVerbOnFile(kUnpinFromTaskbarID, shortcut);
}
} // namespace win
« no previous file with comments | « base/win/shortcut.h ('k') | base/win/win_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698