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

Side by Side 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, 10 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 unified diff | Download patch
« no previous file with comments | « base/win/shortcut.h ('k') | base/win/win_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/win/shortcut.h" 5 #include "base/win/shortcut.h"
6 6
7 #include <shellapi.h> 7 #include <shellapi.h>
8 #include <shldisp.h>
8 #include <shlobj.h> 9 #include <shlobj.h>
9 #include <propkey.h> 10 #include <propkey.h>
10 11
11 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/strings/string_util.h"
12 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
15 #include "base/win/scoped_bstr.h"
13 #include "base/win/scoped_comptr.h" 16 #include "base/win/scoped_comptr.h"
17 #include "base/win/scoped_handle.h"
14 #include "base/win/scoped_propvariant.h" 18 #include "base/win/scoped_propvariant.h"
19 #include "base/win/scoped_variant.h"
15 #include "base/win/win_util.h" 20 #include "base/win/win_util.h"
16 #include "base/win/windows_version.h" 21 #include "base/win/windows_version.h"
17 22
18 namespace base { 23 namespace base {
19 namespace win { 24 namespace win {
20 25
21 namespace { 26 namespace {
22 27
28 // String resource IDs in shell32.dll.
29 const uint32_t kPinToTaskbarID = 5386;
30 const uint32_t kUnpinFromTaskbarID = 5387;
31
32 // Traits for a GenericScopedHandle that will free a module on closure.
33 struct ModuleTraits {
34 typedef HMODULE Handle;
35 static Handle NullHandle() { return nullptr; }
36 static bool IsHandleValid(Handle module) { return !!module; }
37 static bool CloseHandle(Handle module) { return !!::FreeLibrary(module); }
38
39 private:
40 DISALLOW_IMPLICIT_CONSTRUCTORS(ModuleTraits);
41 };
42
43 // An object that will free a module when it goes out of scope.
44 using ScopedLibrary = GenericScopedHandle<ModuleTraits, DummyVerifierTraits>;
45
46 // Returns the shell resource string identified by |resource_id|, or an empty
47 // string on error.
48 string16 LoadShellResourceString(uint32_t resource_id) {
49 ScopedLibrary shell32(::LoadLibrary(L"shell32.dll"));
50 if (!shell32.IsValid())
51 return string16();
52
53 const wchar_t* resource_ptr = nullptr;
54 int length = ::LoadStringW(shell32.Get(), resource_id,
55 reinterpret_cast<wchar_t*>(&resource_ptr), 0);
56 if (!length || !resource_ptr)
57 return string16();
58 return string16(resource_ptr, length);
59 }
60
61 // Uses the shell to perform the verb identified by |resource_id| on |path|.
62 bool DoVerbOnFile(uint32_t resource_id, const FilePath& path) {
63 string16 verb_name(LoadShellResourceString(resource_id));
64 if (verb_name.empty())
65 return false;
66
67 ScopedComPtr<IShellDispatch> shell_dispatch;
68 HRESULT hresult =
69 shell_dispatch.CreateInstance(CLSID_Shell, nullptr, CLSCTX_INPROC_SERVER);
70 if (FAILED(hresult) || !shell_dispatch.get())
71 return false;
72
73 ScopedComPtr<Folder> folder;
74 hresult = shell_dispatch->NameSpace(
75 ScopedVariant(path.DirName().value().c_str()), folder.Receive());
76 if (FAILED(hresult) || !folder.get())
77 return false;
78
79 ScopedComPtr<FolderItem> item;
80 hresult = folder->ParseName(ScopedBstr(path.BaseName().value().c_str()),
81 item.Receive());
82 if (FAILED(hresult) || !item.get())
83 return false;
84
85 ScopedComPtr<FolderItemVerbs> verbs;
86 hresult = item->Verbs(verbs.Receive());
87 if (FAILED(hresult) || !verbs.get())
88 return false;
89
90 long verb_count = 0;
91 hresult = verbs->get_Count(&verb_count);
92 if (FAILED(hresult))
93 return false;
94
95 for (long i = 0; i < verb_count; ++i) {
96 ScopedComPtr<FolderItemVerb> verb;
97 hresult = verbs->Item(ScopedVariant(i, VT_I4), verb.Receive());
98 if (FAILED(hresult) || !verb.get())
99 continue;
100 ScopedBstr name;
101 hresult = verb->get_Name(name.Receive());
102 if (FAILED(hresult))
103 continue;
104 if (StringPiece16(name, name.Length()) == verb_name) {
105 hresult = verb->DoIt();
106 return SUCCEEDED(hresult);
107 }
108 }
109 return false;
110 }
111
23 // Initializes |i_shell_link| and |i_persist_file| (releasing them first if they 112 // Initializes |i_shell_link| and |i_persist_file| (releasing them first if they
24 // are already initialized). 113 // are already initialized).
25 // If |shortcut| is not NULL, loads |shortcut| into |i_persist_file|. 114 // If |shortcut| is not NULL, loads |shortcut| into |i_persist_file|.
26 // If any of the above steps fail, both |i_shell_link| and |i_persist_file| will 115 // If any of the above steps fail, both |i_shell_link| and |i_persist_file| will
27 // be released. 116 // be released.
28 void InitializeShortcutInterfaces( 117 void InitializeShortcutInterfaces(
29 const wchar_t* shortcut, 118 const wchar_t* shortcut,
30 ScopedComPtr<IShellLink>* i_shell_link, 119 ScopedComPtr<IShellLink>* i_shell_link,
31 ScopedComPtr<IPersistFile>* i_persist_file) { 120 ScopedComPtr<IPersistFile>* i_persist_file) {
32 i_shell_link->Release(); 121 i_shell_link->Release();
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 if (!ResolveShortcutProperties(shortcut_path, options, &properties)) 396 if (!ResolveShortcutProperties(shortcut_path, options, &properties))
308 return false; 397 return false;
309 398
310 if (target_path) 399 if (target_path)
311 *target_path = properties.target; 400 *target_path = properties.target;
312 if (args) 401 if (args)
313 *args = properties.arguments; 402 *args = properties.arguments;
314 return true; 403 return true;
315 } 404 }
316 405
317 bool TaskbarPinShortcutLink(const wchar_t* shortcut) { 406 bool TaskbarPinShortcutLink(const FilePath& shortcut) {
318 base::ThreadRestrictions::AssertIOAllowed(); 407 base::ThreadRestrictions::AssertIOAllowed();
319 408
320 // "Pin to taskbar" is only supported after Win7. 409 // "Pin to taskbar" is only supported after Win7.
321 if (GetVersion() < VERSION_WIN7) 410 if (GetVersion() < VERSION_WIN7)
322 return false; 411 return false;
323 412
324 intptr_t result = reinterpret_cast<intptr_t>( 413 return DoVerbOnFile(kPinToTaskbarID, shortcut);
325 ShellExecute(NULL, L"taskbarpin", shortcut, NULL, NULL, 0));
326 return result > 32;
327 } 414 }
328 415
329 bool TaskbarUnpinShortcutLink(const wchar_t* shortcut) { 416 bool TaskbarUnpinShortcutLink(const FilePath& shortcut) {
330 base::ThreadRestrictions::AssertIOAllowed(); 417 base::ThreadRestrictions::AssertIOAllowed();
331 418
332 // "Unpin from taskbar" is only supported after Win7. 419 // "Unpin from taskbar" is only supported after Win7.
333 if (GetVersion() < VERSION_WIN7) 420 if (GetVersion() < VERSION_WIN7)
334 return false; 421 return false;
335 422
336 intptr_t result = reinterpret_cast<intptr_t>( 423 return DoVerbOnFile(kUnpinFromTaskbarID, shortcut);
337 ShellExecute(NULL, L"taskbarunpin", shortcut, NULL, NULL, 0));
338 return result > 32;
339 } 424 }
340 425
341 } // namespace win 426 } // namespace win
342 } // namespace base 427 } // namespace base
OLDNEW
« 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