Chromium Code Reviews| 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.bitfield & ShortcutProperties::PROPERTIES_TARGET) == 0) { |
| 398 DCHECK(source || !create); | 392 NOTREACHED(); |
| 393 return false; | |
| 394 } | |
| 399 | 395 |
| 400 // Length of arguments and description must be less than MAX_PATH. | 396 // Length of arguments and description must be less than MAX_PATH. |
| 401 DCHECK(lstrlen(arguments) < MAX_PATH); | 397 DCHECK(properties.arguments.size() < MAX_PATH); |
| 402 DCHECK(lstrlen(description) < MAX_PATH); | 398 DCHECK(properties.description.size() < MAX_PATH); |
|
robertshield
2012/09/06 02:37:34
Could these DCHECKs be moved to the setters on Sho
gab
2012/09/06 04:20:02
Sounds good to me, unless an argument is made that
| |
| 403 | 399 |
| 404 base::win::ScopedComPtr<IShellLink> i_shell_link; | 400 base::win::ScopedComPtr<IShellLink> i_shell_link; |
| 405 base::win::ScopedComPtr<IPersistFile> i_persist_file; | 401 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, | 402 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, |
| 409 CLSCTX_INPROC_SERVER)) || | 403 CLSCTX_INPROC_SERVER)) || |
| 410 FAILED(i_persist_file.QueryFrom(i_shell_link))) { | 404 FAILED(i_persist_file.QueryFrom(i_shell_link))) { |
| 411 return false; | 405 return false; |
| 412 } | 406 } |
| 413 | 407 |
| 414 if (!create && FAILED(i_persist_file->Load(destination, STGM_READWRITE))) | 408 if (operation == SHORTCUT_UPDATE_EXISTING && |
| 409 FAILED(i_persist_file->Load(shortcut_path.c_str(), STGM_READWRITE))) { | |
| 415 return false; | 410 return false; |
| 411 } | |
| 416 | 412 |
| 417 if ((source || create) && FAILED(i_shell_link->SetPath(source))) | 413 if ((properties.bitfield & ShortcutProperties::PROPERTIES_TARGET) != 0 && |
| 414 FAILED(i_shell_link->SetPath(properties.target.c_str()))) { | |
| 418 return false; | 415 return false; |
| 416 } | |
| 419 | 417 |
| 420 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) | 418 if ((properties.bitfield & ShortcutProperties::PROPERTIES_WORKING_DIR) != 0 && |
| 419 FAILED(i_shell_link->SetWorkingDirectory( | |
| 420 properties.working_dir.c_str()))) { | |
| 421 return false; | 421 return false; |
| 422 } | |
| 422 | 423 |
| 423 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) | 424 if ((properties.bitfield & ShortcutProperties::PROPERTIES_ARGUMENTS) != 0 && |
| 425 FAILED(i_shell_link->SetArguments(properties.arguments.c_str()))) { | |
| 424 return false; | 426 return false; |
| 427 } | |
| 425 | 428 |
| 426 if (description && FAILED(i_shell_link->SetDescription(description))) | 429 if ((properties.bitfield & ShortcutProperties::PROPERTIES_DESCRIPTION) && |
| 430 FAILED(i_shell_link->SetDescription(properties.description.c_str()))) { | |
| 427 return false; | 431 return false; |
| 432 } | |
| 428 | 433 |
| 429 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) | 434 if ((properties.bitfield & ShortcutProperties::PROPERTIES_ICON) && |
| 435 FAILED(i_shell_link->SetIconLocation(properties.icon.c_str(), | |
| 436 properties.icon_index))) { | |
| 430 return false; | 437 return false; |
| 438 } | |
| 431 | 439 |
| 432 bool is_dual_mode = (options & SHORTCUT_DUAL_MODE) != 0; | 440 const bool has_app_id = |
|
robertshield
2012/09/06 02:37:34
don't think adding const here and on has_dual_mode
gab
2012/09/06 04:20:02
I like const here because it's one of those scenar
robertshield
2012/09/06 19:20:01
I'll insist a bit. The additional cognitive load i
gab
2012/09/07 04:58:05
Done.
| |
| 433 if ((app_id || is_dual_mode) && | 441 (properties.bitfield & ShortcutProperties::PROPERTIES_APP_ID) != 0; |
| 442 const bool has_dual_mode = | |
| 443 (properties.bitfield & ShortcutProperties::PROPERTIES_DUAL_MODE) != 0; | |
|
robertshield
2012/09/06 02:37:34
how about:
bool has_dual_mode = (properties.bitfie
gab
2012/09/06 04:20:02
That'd be an implicit cast from int to bool. Not h
robertshield
2012/09/06 19:20:01
I feel it makes the code more readable and I don't
gab
2012/09/07 04:58:05
Tried, but I'm getting warnings->errors:
g:\src\c
| |
| 444 if ((has_app_id || has_dual_mode) && | |
| 434 base::win::GetVersion() >= base::win::VERSION_WIN7) { | 445 base::win::GetVersion() >= base::win::VERSION_WIN7) { |
| 435 base::win::ScopedComPtr<IPropertyStore> property_store; | 446 base::win::ScopedComPtr<IPropertyStore> property_store; |
| 436 if (FAILED(property_store.QueryFrom(i_shell_link)) || !property_store.get()) | 447 if (FAILED(property_store.QueryFrom(i_shell_link)) || !property_store.get()) |
| 437 return false; | 448 return false; |
| 438 | 449 |
| 439 if (app_id && !base::win::SetAppIdForPropertyStore(property_store, app_id)) | 450 if (has_app_id && |
| 451 !base::win::SetAppIdForPropertyStore(property_store, | |
| 452 properties.app_id.c_str())) { | |
| 440 return false; | 453 return false; |
| 441 if (is_dual_mode && | 454 } |
| 442 !base::win::SetDualModeForPropertyStore(property_store)) { | 455 if (has_dual_mode && |
| 456 !base::win::SetDualModeForPropertyStore(property_store, | |
| 457 properties.dual_mode)) { | |
| 443 return false; | 458 return false; |
| 444 } | 459 } |
| 445 } | 460 } |
| 446 | 461 |
| 447 HRESULT result = i_persist_file->Save(destination, TRUE); | 462 HRESULT result = i_persist_file->Save(shortcut_path.c_str(), TRUE); |
| 448 | 463 |
| 449 // If we successfully updated the icon, notify the shell that we have done so. | 464 // If we successfully updated the icon, notify the shell that we have done so. |
| 450 if (!create && SUCCEEDED(result)) { | 465 if (operation == SHORTCUT_UPDATE_EXISTING && SUCCEEDED(result)) { |
| 451 // Release the interfaces in case the SHChangeNotify call below depends on | 466 // Release the interfaces in case the SHChangeNotify call below depends on |
| 452 // the operations above being fully completed. | 467 // the operations above being fully completed. |
| 453 i_persist_file.Release(); | 468 i_persist_file.Release(); |
| 454 i_shell_link.Release(); | 469 i_shell_link.Release(); |
| 455 | 470 |
| 456 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); | 471 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); |
| 457 } | 472 } |
| 458 | 473 |
| 459 return SUCCEEDED(result); | 474 return SUCCEEDED(result); |
| 460 } | 475 } |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1122 HANDLE cp = GetCurrentProcess(); | 1137 HANDLE cp = GetCurrentProcess(); |
| 1123 if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) { | 1138 if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) { |
| 1124 *nt_path = FilePath(mapped_file_path); | 1139 *nt_path = FilePath(mapped_file_path); |
| 1125 success = true; | 1140 success = true; |
| 1126 } | 1141 } |
| 1127 ::UnmapViewOfFile(file_view); | 1142 ::UnmapViewOfFile(file_view); |
| 1128 return success; | 1143 return success; |
| 1129 } | 1144 } |
| 1130 | 1145 |
| 1131 } // namespace file_util | 1146 } // namespace file_util |
| OLD | NEW |