OLD | NEW |
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 <shlobj.h> | 8 #include <shlobj.h> |
9 #include <propkey.h> | 9 #include <propkey.h> |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 // If any of the above steps fail, both |i_shell_link| and |i_persist_file| will | 26 // If any of the above steps fail, both |i_shell_link| and |i_persist_file| will |
27 // be released. | 27 // be released. |
28 void InitializeShortcutInterfaces( | 28 void InitializeShortcutInterfaces( |
29 const wchar_t* shortcut, | 29 const wchar_t* shortcut, |
30 ScopedComPtr<IShellLink>* i_shell_link, | 30 ScopedComPtr<IShellLink>* i_shell_link, |
31 ScopedComPtr<IPersistFile>* i_persist_file) { | 31 ScopedComPtr<IPersistFile>* i_persist_file) { |
32 i_shell_link->Reset(); | 32 i_shell_link->Reset(); |
33 i_persist_file->Reset(); | 33 i_persist_file->Reset(); |
34 if (FAILED(i_shell_link->CreateInstance(CLSID_ShellLink, NULL, | 34 if (FAILED(i_shell_link->CreateInstance(CLSID_ShellLink, NULL, |
35 CLSCTX_INPROC_SERVER)) || | 35 CLSCTX_INPROC_SERVER)) || |
36 FAILED(i_persist_file->QueryFrom(i_shell_link->get())) || | 36 FAILED(i_persist_file->QueryFrom(i_shell_link->Get())) || |
37 (shortcut && FAILED((*i_persist_file)->Load(shortcut, STGM_READWRITE)))) { | 37 (shortcut && FAILED((*i_persist_file)->Load(shortcut, STGM_READWRITE)))) { |
38 i_shell_link->Reset(); | 38 i_shell_link->Reset(); |
39 i_persist_file->Reset(); | 39 i_persist_file->Reset(); |
40 } | 40 } |
41 } | 41 } |
42 | 42 |
43 } // namespace | 43 } // namespace |
44 | 44 |
45 ShortcutProperties::ShortcutProperties() | 45 ShortcutProperties::ShortcutProperties() |
46 : icon_index(-1), dual_mode(false), options(0U) { | 46 : icon_index(-1), dual_mode(false), options(0U) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 InitializeShortcutInterfaces(shortcut_path.value().c_str(), &i_shell_link, | 81 InitializeShortcutInterfaces(shortcut_path.value().c_str(), &i_shell_link, |
82 &i_persist_file); | 82 &i_persist_file); |
83 break; | 83 break; |
84 case SHORTCUT_REPLACE_EXISTING: | 84 case SHORTCUT_REPLACE_EXISTING: |
85 InitializeShortcutInterfaces(shortcut_path.value().c_str(), | 85 InitializeShortcutInterfaces(shortcut_path.value().c_str(), |
86 &old_i_shell_link, &old_i_persist_file); | 86 &old_i_shell_link, &old_i_persist_file); |
87 // Confirm |shortcut_path| exists and is a shortcut by verifying | 87 // Confirm |shortcut_path| exists and is a shortcut by verifying |
88 // |old_i_persist_file| was successfully initialized in the call above. If | 88 // |old_i_persist_file| was successfully initialized in the call above. If |
89 // so, initialize the interfaces to begin writing a new shortcut (to | 89 // so, initialize the interfaces to begin writing a new shortcut (to |
90 // overwrite the current one if successful). | 90 // overwrite the current one if successful). |
91 if (old_i_persist_file.get()) | 91 if (old_i_persist_file.Get()) |
92 InitializeShortcutInterfaces(NULL, &i_shell_link, &i_persist_file); | 92 InitializeShortcutInterfaces(NULL, &i_shell_link, &i_persist_file); |
93 break; | 93 break; |
94 default: | 94 default: |
95 NOTREACHED(); | 95 NOTREACHED(); |
96 } | 96 } |
97 | 97 |
98 // Return false immediately upon failure to initialize shortcut interfaces. | 98 // Return false immediately upon failure to initialize shortcut interfaces. |
99 if (!i_persist_file.get()) | 99 if (!i_persist_file.Get()) |
100 return false; | 100 return false; |
101 | 101 |
102 if ((properties.options & ShortcutProperties::PROPERTIES_TARGET) && | 102 if ((properties.options & ShortcutProperties::PROPERTIES_TARGET) && |
103 FAILED(i_shell_link->SetPath(properties.target.value().c_str()))) { | 103 FAILED(i_shell_link->SetPath(properties.target.value().c_str()))) { |
104 return false; | 104 return false; |
105 } | 105 } |
106 | 106 |
107 if ((properties.options & ShortcutProperties::PROPERTIES_WORKING_DIR) && | 107 if ((properties.options & ShortcutProperties::PROPERTIES_WORKING_DIR) && |
108 FAILED(i_shell_link->SetWorkingDirectory( | 108 FAILED(i_shell_link->SetWorkingDirectory( |
109 properties.working_dir.value().c_str()))) { | 109 properties.working_dir.value().c_str()))) { |
110 return false; | 110 return false; |
111 } | 111 } |
112 | 112 |
113 if (properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) { | 113 if (properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) { |
114 if (FAILED(i_shell_link->SetArguments(properties.arguments.c_str()))) | 114 if (FAILED(i_shell_link->SetArguments(properties.arguments.c_str()))) |
115 return false; | 115 return false; |
116 } else if (old_i_persist_file.get()) { | 116 } else if (old_i_persist_file.Get()) { |
117 wchar_t current_arguments[MAX_PATH] = {0}; | 117 wchar_t current_arguments[MAX_PATH] = {0}; |
118 if (SUCCEEDED(old_i_shell_link->GetArguments(current_arguments, | 118 if (SUCCEEDED(old_i_shell_link->GetArguments(current_arguments, |
119 MAX_PATH))) { | 119 MAX_PATH))) { |
120 i_shell_link->SetArguments(current_arguments); | 120 i_shell_link->SetArguments(current_arguments); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 if ((properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) && | 124 if ((properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) && |
125 FAILED(i_shell_link->SetDescription(properties.description.c_str()))) { | 125 FAILED(i_shell_link->SetDescription(properties.description.c_str()))) { |
126 return false; | 126 return false; |
127 } | 127 } |
128 | 128 |
129 if ((properties.options & ShortcutProperties::PROPERTIES_ICON) && | 129 if ((properties.options & ShortcutProperties::PROPERTIES_ICON) && |
130 FAILED(i_shell_link->SetIconLocation(properties.icon.value().c_str(), | 130 FAILED(i_shell_link->SetIconLocation(properties.icon.value().c_str(), |
131 properties.icon_index))) { | 131 properties.icon_index))) { |
132 return false; | 132 return false; |
133 } | 133 } |
134 | 134 |
135 bool has_app_id = | 135 bool has_app_id = |
136 (properties.options & ShortcutProperties::PROPERTIES_APP_ID) != 0; | 136 (properties.options & ShortcutProperties::PROPERTIES_APP_ID) != 0; |
137 bool has_dual_mode = | 137 bool has_dual_mode = |
138 (properties.options & ShortcutProperties::PROPERTIES_DUAL_MODE) != 0; | 138 (properties.options & ShortcutProperties::PROPERTIES_DUAL_MODE) != 0; |
139 if ((has_app_id || has_dual_mode) && | 139 if ((has_app_id || has_dual_mode) && |
140 GetVersion() >= VERSION_WIN7) { | 140 GetVersion() >= VERSION_WIN7) { |
141 ScopedComPtr<IPropertyStore> property_store; | 141 ScopedComPtr<IPropertyStore> property_store; |
142 if (FAILED(property_store.QueryFrom(i_shell_link.get())) || | 142 if (FAILED(property_store.QueryFrom(i_shell_link.Get())) || |
143 !property_store.get()) | 143 !property_store.Get()) |
144 return false; | 144 return false; |
145 | 145 |
146 if (has_app_id && | 146 if (has_app_id && |
147 !SetAppIdForPropertyStore(property_store.get(), | 147 !SetAppIdForPropertyStore(property_store.Get(), |
148 properties.app_id.c_str())) { | 148 properties.app_id.c_str())) { |
149 return false; | 149 return false; |
150 } | 150 } |
151 if (has_dual_mode && | 151 if (has_dual_mode && |
152 !SetBooleanValueForPropertyStore(property_store.get(), | 152 !SetBooleanValueForPropertyStore(property_store.Get(), |
153 PKEY_AppUserModel_IsDualMode, | 153 PKEY_AppUserModel_IsDualMode, |
154 properties.dual_mode)) { | 154 properties.dual_mode)) { |
155 return false; | 155 return false; |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 // Release the interfaces to the old shortcut to make sure it doesn't prevent | 159 // Release the interfaces to the old shortcut to make sure it doesn't prevent |
160 // overwriting it if needed. | 160 // overwriting it if needed. |
161 old_i_persist_file.Reset(); | 161 old_i_persist_file.Reset(); |
162 old_i_shell_link.Reset(); | 162 old_i_shell_link.Reset(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 ScopedComPtr<IShellLink> i_shell_link; | 197 ScopedComPtr<IShellLink> i_shell_link; |
198 | 198 |
199 // Get pointer to the IShellLink interface. | 199 // Get pointer to the IShellLink interface. |
200 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, | 200 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, |
201 CLSCTX_INPROC_SERVER))) { | 201 CLSCTX_INPROC_SERVER))) { |
202 return false; | 202 return false; |
203 } | 203 } |
204 | 204 |
205 ScopedComPtr<IPersistFile> persist; | 205 ScopedComPtr<IPersistFile> persist; |
206 // Query IShellLink for the IPersistFile interface. | 206 // Query IShellLink for the IPersistFile interface. |
207 if (FAILED(persist.QueryFrom(i_shell_link.get()))) | 207 if (FAILED(persist.QueryFrom(i_shell_link.Get()))) |
208 return false; | 208 return false; |
209 | 209 |
210 // Load the shell link. | 210 // Load the shell link. |
211 if (FAILED(persist->Load(shortcut_path.value().c_str(), STGM_READ))) | 211 if (FAILED(persist->Load(shortcut_path.value().c_str(), STGM_READ))) |
212 return false; | 212 return false; |
213 | 213 |
214 // Reset |properties|. | 214 // Reset |properties|. |
215 properties->options = 0; | 215 properties->options = 0; |
216 | 216 |
217 wchar_t temp[MAX_PATH]; | 217 wchar_t temp[MAX_PATH]; |
(...skipping 26 matching lines...) Expand all Loading... |
244 int temp_index; | 244 int temp_index; |
245 if (FAILED(i_shell_link->GetIconLocation(temp, MAX_PATH, &temp_index))) | 245 if (FAILED(i_shell_link->GetIconLocation(temp, MAX_PATH, &temp_index))) |
246 return false; | 246 return false; |
247 properties->set_icon(FilePath(temp), temp_index); | 247 properties->set_icon(FilePath(temp), temp_index); |
248 } | 248 } |
249 | 249 |
250 // Windows 7+ options, avoiding unnecessary work. | 250 // Windows 7+ options, avoiding unnecessary work. |
251 if ((options & ShortcutProperties::PROPERTIES_WIN7) && | 251 if ((options & ShortcutProperties::PROPERTIES_WIN7) && |
252 GetVersion() >= VERSION_WIN7) { | 252 GetVersion() >= VERSION_WIN7) { |
253 ScopedComPtr<IPropertyStore> property_store; | 253 ScopedComPtr<IPropertyStore> property_store; |
254 if (FAILED(property_store.QueryFrom(i_shell_link.get()))) | 254 if (FAILED(property_store.QueryFrom(i_shell_link.Get()))) |
255 return false; | 255 return false; |
256 | 256 |
257 if (options & ShortcutProperties::PROPERTIES_APP_ID) { | 257 if (options & ShortcutProperties::PROPERTIES_APP_ID) { |
258 ScopedPropVariant pv_app_id; | 258 ScopedPropVariant pv_app_id; |
259 if (property_store->GetValue(PKEY_AppUserModel_ID, | 259 if (property_store->GetValue(PKEY_AppUserModel_ID, |
260 pv_app_id.Receive()) != S_OK) { | 260 pv_app_id.Receive()) != S_OK) { |
261 return false; | 261 return false; |
262 } | 262 } |
263 switch (pv_app_id.get().vt) { | 263 switch (pv_app_id.get().vt) { |
264 case VT_EMPTY: | 264 case VT_EMPTY: |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 if (GetVersion() < VERSION_WIN7) | 340 if (GetVersion() < VERSION_WIN7) |
341 return false; | 341 return false; |
342 | 342 |
343 intptr_t result = reinterpret_cast<intptr_t>(ShellExecute( | 343 intptr_t result = reinterpret_cast<intptr_t>(ShellExecute( |
344 NULL, L"taskbarunpin", shortcut.value().c_str(), NULL, NULL, 0)); | 344 NULL, L"taskbarunpin", shortcut.value().c_str(), NULL, NULL, 0)); |
345 return result > 32; | 345 return result > 32; |
346 } | 346 } |
347 | 347 |
348 } // namespace win | 348 } // namespace win |
349 } // namespace base | 349 } // namespace base |
OLD | NEW |