| 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 |