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

Side by Side Diff: base/test/test_shortcut_win.cc

Issue 10914109: Refactoring and tests for the highly undertested file_util::CreateOrUpdateShortcutLink() method. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: string16 to FilePath where appropriate Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/test/test_shortcut_win.h"
6
7 #include <windows.h>
8 #include <shlobj.h>
9 #include <propkey.h>
10 #include <propvarutil.h>
11
12 #include "base/file_path.h"
13 #include "base/string16.h"
14 #include "base/win/scoped_comptr.h"
15 #include "base/win/windows_version.h"
16
17 // propsys.lib is required for PropvariantTo*().
18 #pragma comment(lib, "propsys.lib")
19
20 namespace base {
21 namespace win {
22
23 namespace {
24
25 // Returns true if |actual_path|'s LongPathName case-insensitively matches
26 // |expected_path|'s LongPathName.
27 bool PathsAreEqual(const FilePath& expected_path, const FilePath& actual_path) {
28 wchar_t long_expected_path_chars[MAX_PATH] = {0};
29 wchar_t long_actual_path_chars[MAX_PATH] = {0};
30
31 if (::GetLongPathName(
32 expected_path.value().c_str(), long_expected_path_chars,
33 MAX_PATH) == 0 ||
34 ::GetLongPathName(
35 actual_path.value().c_str(), long_actual_path_chars,
36 MAX_PATH) == 0) {
37 return false;
38 }
39
40 FilePath long_expected_path(long_expected_path_chars);
41 FilePath long_actual_path(long_actual_path_chars);
42 if(long_expected_path.empty() || long_actual_path.empty())
43 return false;
44
45 return long_expected_path == long_actual_path;
46 }
47
48 } // namespace
49
50 VerifyShortcutStatus VerifyShortcut(const FilePath& shortcut_path,
51 const ShortcutProperties& properties) {
52 ScopedComPtr<IShellLink> i_shell_link;
53 ScopedComPtr<IPersistFile> i_persist_file;
54
55 wchar_t read_target[MAX_PATH] = {0};
56 wchar_t read_working_dir[MAX_PATH] = {0};
57 wchar_t read_arguments[MAX_PATH] = {0};
58 wchar_t read_description[MAX_PATH] = {0};
59 wchar_t read_icon[MAX_PATH] = {0};
60 int read_icon_index = 0;
61
62 // Initialize the shell interfaces.
63 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
64 CLSCTX_INPROC_SERVER)) ||
65 FAILED(i_persist_file.QueryFrom(i_shell_link))) {
66 return VERIFY_SHORTCUT_FAILURE_UNEXPECTED;
67 }
68
69 // Load the shortcut.
70 if (FAILED(i_persist_file->Load(shortcut_path.value().c_str(), 0)))
71 return VERIFY_SHORTCUT_FAILURE_FILE_NOT_FOUND;
72
73 if ((properties.options & ShortcutProperties::PROPERTIES_TARGET) &&
74 (FAILED(i_shell_link->GetPath(
75 read_target, MAX_PATH, NULL, SLGP_SHORTPATH)) ||
76 !PathsAreEqual(properties.target, FilePath(read_target)))) {
77 return VERIFY_SHORTCUT_FAILURE_TARGET;
78 }
79
80 if ((properties.options & ShortcutProperties::PROPERTIES_WORKING_DIR) &&
81 (FAILED(i_shell_link->GetWorkingDirectory(read_working_dir, MAX_PATH)) ||
82 FilePath(read_working_dir) != properties.working_dir)) {
83 return VERIFY_SHORTCUT_FAILURE_WORKING_DIR;
84 }
85
86 if ((properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) &&
87 (FAILED(i_shell_link->GetArguments(read_arguments, MAX_PATH)) ||
88 string16(read_arguments) != properties.arguments)) {
89 return VERIFY_SHORTCUT_FAILURE_ARGUMENTS;
90 }
91
92 if ((properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) &&
93 (FAILED(i_shell_link->GetDescription(read_description, MAX_PATH)) ||
94 string16(read_description) != properties.description)) {
95 return VERIFY_SHORTCUT_FAILURE_DESCRIPTION;
96 }
97
98 if ((properties.options & ShortcutProperties::PROPERTIES_ICON) &&
99 (FAILED(i_shell_link->GetIconLocation(read_icon, MAX_PATH,
100 &read_icon_index)) ||
101 read_icon_index != properties.icon_index ||
102 !PathsAreEqual(properties.icon, FilePath(read_icon)))) {
103 return VERIFY_SHORTCUT_FAILURE_ICON;
104 }
105
106 if(GetVersion() >= VERSION_WIN7) {
107 ScopedComPtr<IPropertyStore> property_store;
108 // Note that, as mentioned on MSDN at http://goo.gl/M8h9g, if a property is
109 // not set, GetValue will return S_OK and the PROPVARIANT will be set to
110 // VT_EMPTY.
111 PROPVARIANT pv_app_id, pv_dual_mode;
112 if (FAILED(property_store.QueryFrom(i_shell_link)) ||
113 property_store->GetValue(PKEY_AppUserModel_ID, &pv_app_id) != S_OK ||
114 property_store->GetValue(PKEY_AppUserModel_IsDualMode,
115 &pv_dual_mode) != S_OK) {
116 return VERIFY_SHORTCUT_FAILURE_UNEXPECTED;
117 }
118
119 // Note, as mentioned on MSDN at http://goo.gl/hZ3sO, if |pv_app_id| is a
120 // VT_EMPTY it is successfully converted to the empty string.
121 wchar_t read_app_id[MAX_PATH] = {0};
122 PropVariantToString(pv_app_id, read_app_id, MAX_PATH);
123 if((properties.options & ShortcutProperties::PROPERTIES_APP_ID) &&
124 string16(read_app_id) != properties.app_id) {
125 return VERIFY_SHORTCUT_FAILURE_APP_ID;
126 }
127
128 // Note, as mentioned on MSDN at http://goo.gl/9mBHB, if |pv_dual_mode| is a
129 // VT_EMPTY it is successfully converted to false.
130 BOOL read_dual_mode;
131 PropVariantToBoolean(pv_dual_mode, &read_dual_mode);
132 if((properties.options & ShortcutProperties::PROPERTIES_DUAL_MODE) &&
133 static_cast<bool>(read_dual_mode) != properties.dual_mode) {
134 return VERIFY_SHORTCUT_FAILURE_DUAL_MODE;
135 }
136 }
137
138 return VERIFY_SHORTCUT_SUCCESS;
139 }
140
141 } // namespace win
142 } // namespace base
OLDNEW
« no previous file with comments | « base/test/test_shortcut_win.h ('k') | base/win/shortcut.h » ('j') | base/win/shortcut.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698