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/file_util.h" | 5 #include "base/file_util.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <propvarutil.h> | 8 #include <propvarutil.h> |
9 #include <psapi.h> | 9 #include <psapi.h> |
10 #include <shellapi.h> | 10 #include <shellapi.h> |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 if (args) { | 374 if (args) { |
375 result = i_shell_link->GetArguments(temp, MAX_PATH); | 375 result = i_shell_link->GetArguments(temp, MAX_PATH); |
376 if (FAILED(result)) | 376 if (FAILED(result)) |
377 return false; | 377 return false; |
378 | 378 |
379 *args = string16(temp); | 379 *args = string16(temp); |
380 } | 380 } |
381 return true; | 381 return true; |
382 } | 382 } |
383 | 383 |
384 bool CreateOrUpdateShortcutLink(const wchar_t *source, | 384 bool CreateOrUpdateShortcutLink(const string16& shortcut_path, |
385 const wchar_t *destination, | 385 const ShortcutProperties& properties, |
386 const wchar_t *working_dir, | 386 ShortcutOperation operation) { |
387 const wchar_t *arguments, | |
388 const wchar_t *description, | |
389 const wchar_t *icon, | |
390 int icon_index, | |
391 const wchar_t* app_id, | |
392 uint32 options) { | |
393 base::ThreadRestrictions::AssertIOAllowed(); | 387 base::ThreadRestrictions::AssertIOAllowed(); |
394 | 388 |
395 bool create = (options & SHORTCUT_CREATE_ALWAYS) != 0; | 389 // A target is required when |operation| is SHORTCUT_CREATE_ALWAYS. |
396 | 390 if (operation == SHORTCUT_CREATE_ALWAYS && |
397 // |source| is required when SHORTCUT_CREATE_ALWAYS is specified. | 391 !(properties.options & ShortcutProperties::PROPERTIES_TARGET)) { |
398 DCHECK(source || !create); | 392 NOTREACHED(); |
399 | 393 return false; |
400 // Length of arguments and description must be less than MAX_PATH. | 394 } |
401 DCHECK(lstrlen(arguments) < MAX_PATH); | |
402 DCHECK(lstrlen(description) < MAX_PATH); | |
403 | 395 |
404 base::win::ScopedComPtr<IShellLink> i_shell_link; | 396 base::win::ScopedComPtr<IShellLink> i_shell_link; |
405 base::win::ScopedComPtr<IPersistFile> i_persist_file; | 397 base::win::ScopedComPtr<IPersistFile> i_persist_file; |
406 | |
407 // Get pointer to the IShellLink interface. | |
408 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, | 398 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, |
409 CLSCTX_INPROC_SERVER)) || | 399 CLSCTX_INPROC_SERVER)) || |
410 FAILED(i_persist_file.QueryFrom(i_shell_link))) { | 400 FAILED(i_persist_file.QueryFrom(i_shell_link))) { |
411 return false; | 401 return false; |
412 } | 402 } |
413 | 403 |
414 if (!create && FAILED(i_persist_file->Load(destination, STGM_READWRITE))) | 404 if (operation == SHORTCUT_UPDATE_EXISTING && |
| 405 FAILED(i_persist_file->Load(shortcut_path.c_str(), STGM_READWRITE))) { |
415 return false; | 406 return false; |
| 407 } |
416 | 408 |
417 if ((source || create) && FAILED(i_shell_link->SetPath(source))) | 409 if ((properties.options & ShortcutProperties::PROPERTIES_TARGET) && |
| 410 FAILED(i_shell_link->SetPath(properties.target.c_str()))) { |
418 return false; | 411 return false; |
| 412 } |
419 | 413 |
420 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) | 414 if ((properties.options & ShortcutProperties::PROPERTIES_WORKING_DIR) && |
| 415 FAILED(i_shell_link->SetWorkingDirectory( |
| 416 properties.working_dir.c_str()))) { |
421 return false; | 417 return false; |
| 418 } |
422 | 419 |
423 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) | 420 if ((properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) && |
| 421 FAILED(i_shell_link->SetArguments(properties.arguments.c_str()))) { |
424 return false; | 422 return false; |
| 423 } |
425 | 424 |
426 if (description && FAILED(i_shell_link->SetDescription(description))) | 425 if ((properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) && |
| 426 FAILED(i_shell_link->SetDescription(properties.description.c_str()))) { |
427 return false; | 427 return false; |
| 428 } |
428 | 429 |
429 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) | 430 if ((properties.options & ShortcutProperties::PROPERTIES_ICON) && |
| 431 FAILED(i_shell_link->SetIconLocation(properties.icon.c_str(), |
| 432 properties.icon_index))) { |
430 return false; | 433 return false; |
| 434 } |
431 | 435 |
432 bool is_dual_mode = (options & SHORTCUT_DUAL_MODE) != 0; | 436 const bool has_app_id = |
433 if ((app_id || is_dual_mode) && | 437 (properties.options & ShortcutProperties::PROPERTIES_APP_ID) != 0; |
| 438 const bool has_dual_mode = |
| 439 (properties.options & ShortcutProperties::PROPERTIES_DUAL_MODE) != 0; |
| 440 if ((has_app_id || has_dual_mode) && |
434 base::win::GetVersion() >= base::win::VERSION_WIN7) { | 441 base::win::GetVersion() >= base::win::VERSION_WIN7) { |
435 base::win::ScopedComPtr<IPropertyStore> property_store; | 442 base::win::ScopedComPtr<IPropertyStore> property_store; |
436 if (FAILED(property_store.QueryFrom(i_shell_link)) || !property_store.get()) | 443 if (FAILED(property_store.QueryFrom(i_shell_link)) || !property_store.get()) |
437 return false; | 444 return false; |
438 | 445 |
439 if (app_id && !base::win::SetAppIdForPropertyStore(property_store, app_id)) | 446 if (has_app_id && |
| 447 !base::win::SetAppIdForPropertyStore(property_store, |
| 448 properties.app_id.c_str())) { |
440 return false; | 449 return false; |
441 if (is_dual_mode && | 450 } |
442 !base::win::SetDualModeForPropertyStore(property_store)) { | 451 if (has_dual_mode && |
| 452 !base::win::SetDualModeForPropertyStore(property_store, |
| 453 properties.dual_mode)) { |
443 return false; | 454 return false; |
444 } | 455 } |
445 } | 456 } |
446 | 457 |
447 HRESULT result = i_persist_file->Save(destination, TRUE); | 458 HRESULT result = i_persist_file->Save(shortcut_path.c_str(), TRUE); |
448 | 459 |
449 // If we successfully updated the icon, notify the shell that we have done so. | 460 // If we successfully updated the icon, notify the shell that we have done so. |
450 if (!create && SUCCEEDED(result)) { | 461 if (operation == SHORTCUT_UPDATE_EXISTING && SUCCEEDED(result)) { |
451 // Release the interfaces in case the SHChangeNotify call below depends on | 462 // Release the interfaces in case the SHChangeNotify call below depends on |
452 // the operations above being fully completed. | 463 // the operations above being fully completed. |
453 i_persist_file.Release(); | 464 i_persist_file.Release(); |
454 i_shell_link.Release(); | 465 i_shell_link.Release(); |
455 | 466 |
456 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); | 467 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); |
457 } | 468 } |
458 | 469 |
459 return SUCCEEDED(result); | 470 return SUCCEEDED(result); |
460 } | 471 } |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 HANDLE cp = GetCurrentProcess(); | 1133 HANDLE cp = GetCurrentProcess(); |
1123 if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) { | 1134 if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) { |
1124 *nt_path = FilePath(mapped_file_path); | 1135 *nt_path = FilePath(mapped_file_path); |
1125 success = true; | 1136 success = true; |
1126 } | 1137 } |
1127 ::UnmapViewOfFile(file_view); | 1138 ::UnmapViewOfFile(file_view); |
1128 return success; | 1139 return success; |
1129 } | 1140 } |
1130 | 1141 |
1131 } // namespace file_util | 1142 } // namespace file_util |
OLD | NEW |