OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <shellapi.h> | 9 #include <shellapi.h> |
9 #include <shlobj.h> | 10 #include <shlobj.h> |
10 #include <time.h> | 11 #include <time.h> |
11 #include <string> | 12 #include <string> |
12 | 13 |
13 #include "base/file_path.h" | 14 #include "base/file_path.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/scoped_comptr_win.h" |
15 #include "base/scoped_handle.h" | 17 #include "base/scoped_handle.h" |
16 #include "base/string_util.h" | 18 #include "base/string_util.h" |
17 #include "base/time.h" | 19 #include "base/time.h" |
18 #include "base/win_util.h" | 20 #include "base/win_util.h" |
19 | 21 |
20 namespace file_util { | 22 namespace file_util { |
21 | 23 |
22 std::wstring GetDirectoryFromPath(const std::wstring& path) { | 24 std::wstring GetDirectoryFromPath(const std::wstring& path) { |
23 wchar_t path_buffer[MAX_PATH]; | 25 wchar_t path_buffer[MAX_PATH]; |
24 wchar_t* file_ptr = NULL; | 26 wchar_t* file_ptr = NULL; |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 LPSYSTEMTIME creation_time) { | 253 LPSYSTEMTIME creation_time) { |
252 ScopedHandle file_handle( | 254 ScopedHandle file_handle( |
253 CreateFile(filename.c_str(), GENERIC_READ, | 255 CreateFile(filename.c_str(), GENERIC_READ, |
254 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, | 256 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
255 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); | 257 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); |
256 return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); | 258 return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); |
257 } | 259 } |
258 | 260 |
259 bool ResolveShortcut(FilePath* path) { | 261 bool ResolveShortcut(FilePath* path) { |
260 HRESULT result; | 262 HRESULT result; |
261 IShellLink *shell = NULL; | 263 ScopedComPtr<IShellLink> i_shell_link; |
262 bool is_resolved = false; | 264 bool is_resolved = false; |
263 | 265 |
264 // Get pointer to the IShellLink interface | 266 // Get pointer to the IShellLink interface |
265 result = CoCreateInstance(CLSID_ShellLink, NULL, | 267 result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, |
266 CLSCTX_INPROC_SERVER, IID_IShellLink, | 268 CLSCTX_INPROC_SERVER); |
267 reinterpret_cast<LPVOID*>(&shell)); | |
268 if (SUCCEEDED(result)) { | 269 if (SUCCEEDED(result)) { |
269 IPersistFile *persist = NULL; | 270 ScopedComPtr<IPersistFile> persist; |
270 // Query IShellLink for the IPersistFile interface | 271 // Query IShellLink for the IPersistFile interface |
271 result = shell->QueryInterface(IID_IPersistFile, | 272 result = persist.QueryFrom(i_shell_link); |
272 reinterpret_cast<LPVOID*>(&persist)); | |
273 if (SUCCEEDED(result)) { | 273 if (SUCCEEDED(result)) { |
274 WCHAR temp_path[MAX_PATH]; | 274 WCHAR temp_path[MAX_PATH]; |
275 // Load the shell link | 275 // Load the shell link |
276 result = persist->Load(path->value().c_str(), STGM_READ); | 276 result = persist->Load(path->value().c_str(), STGM_READ); |
277 if (SUCCEEDED(result)) { | 277 if (SUCCEEDED(result)) { |
278 // Try to find the target of a shortcut | 278 // Try to find the target of a shortcut |
279 result = shell->Resolve(0, SLR_NO_UI); | 279 result = i_shell_link->Resolve(0, SLR_NO_UI); |
280 if (SUCCEEDED(result)) { | 280 if (SUCCEEDED(result)) { |
281 result = shell->GetPath(temp_path, MAX_PATH, | 281 result = i_shell_link->GetPath(temp_path, MAX_PATH, |
282 NULL, SLGP_UNCPRIORITY); | 282 NULL, SLGP_UNCPRIORITY); |
283 *path = FilePath(temp_path); | 283 *path = FilePath(temp_path); |
284 is_resolved = true; | 284 is_resolved = true; |
285 } | 285 } |
286 } | 286 } |
287 } | 287 } |
288 if (persist) | |
289 persist->Release(); | |
290 } | 288 } |
291 if (shell) | |
292 shell->Release(); | |
293 | 289 |
294 return is_resolved; | 290 return is_resolved; |
295 } | 291 } |
296 | 292 |
297 bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination, | 293 bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination, |
298 const wchar_t *working_dir, const wchar_t *arguments, | 294 const wchar_t *working_dir, const wchar_t *arguments, |
299 const wchar_t *description, const wchar_t *icon, | 295 const wchar_t *description, const wchar_t *icon, |
300 int icon_index) { | 296 int icon_index, const wchar_t* app_id) { |
301 IShellLink *i_shell_link = NULL; | 297 ScopedComPtr<IShellLink> i_shell_link; |
302 IPersistFile *i_persist_file = NULL; | 298 ScopedComPtr<IPersistFile> i_persist_file; |
303 | 299 |
304 // Get pointer to the IShellLink interface | 300 // Get pointer to the IShellLink interface |
305 HRESULT result = CoCreateInstance(CLSID_ShellLink, NULL, | 301 HRESULT result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, |
306 CLSCTX_INPROC_SERVER, IID_IShellLink, | 302 CLSCTX_INPROC_SERVER); |
307 reinterpret_cast<LPVOID*>(&i_shell_link)); | |
308 if (FAILED(result)) | 303 if (FAILED(result)) |
309 return false; | 304 return false; |
310 | 305 |
311 // Query IShellLink for the IPersistFile interface | 306 // Query IShellLink for the IPersistFile interface |
312 result = i_shell_link->QueryInterface(IID_IPersistFile, | 307 result = i_persist_file.QueryFrom(i_shell_link); |
313 reinterpret_cast<LPVOID*>(&i_persist_file)); | 308 if (FAILED(result)) |
314 if (FAILED(result)) { | |
315 i_shell_link->Release(); | |
316 return false; | 309 return false; |
317 } | |
318 | 310 |
319 if (FAILED(i_shell_link->SetPath(source))) { | 311 if (FAILED(i_shell_link->SetPath(source))) |
320 i_persist_file->Release(); | |
321 i_shell_link->Release(); | |
322 return false; | 312 return false; |
323 } | |
324 | 313 |
325 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) { | 314 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) |
326 i_persist_file->Release(); | |
327 i_shell_link->Release(); | |
328 return false; | 315 return false; |
329 } | |
330 | 316 |
331 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) { | 317 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) |
332 i_persist_file->Release(); | |
333 i_shell_link->Release(); | |
334 return false; | 318 return false; |
335 } | |
336 | 319 |
337 if (description && FAILED(i_shell_link->SetDescription(description))) { | 320 if (description && FAILED(i_shell_link->SetDescription(description))) |
338 i_persist_file->Release(); | |
339 i_shell_link->Release(); | |
340 return false; | 321 return false; |
341 } | |
342 | 322 |
343 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) { | 323 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) |
344 i_persist_file->Release(); | |
345 i_shell_link->Release(); | |
346 return false; | 324 return false; |
| 325 |
| 326 if (app_id && (win_util::GetWinVersion() >= win_util::WINVERSION_WIN7)) { |
| 327 ScopedComPtr<IPropertyStore> property_store; |
| 328 if (FAILED(property_store.QueryFrom(i_shell_link))) |
| 329 return false; |
| 330 |
| 331 if (!win_util::SetAppIdForPropertyStore(property_store, app_id)) |
| 332 return false; |
347 } | 333 } |
348 | 334 |
349 result = i_persist_file->Save(destination, TRUE); | 335 result = i_persist_file->Save(destination, TRUE); |
350 i_persist_file->Release(); | |
351 i_shell_link->Release(); | |
352 return SUCCEEDED(result); | 336 return SUCCEEDED(result); |
353 } | 337 } |
354 | 338 |
355 | 339 |
356 bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination, | 340 bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination, |
357 const wchar_t *working_dir, const wchar_t *arguments, | 341 const wchar_t *working_dir, const wchar_t *arguments, |
358 const wchar_t *description, const wchar_t *icon, | 342 const wchar_t *description, const wchar_t *icon, |
359 int icon_index) { | 343 int icon_index, const wchar_t* app_id) { |
360 // Get pointer to the IPersistFile interface and load existing link | 344 // Get pointer to the IPersistFile interface and load existing link |
361 IShellLink *i_shell_link = NULL; | 345 ScopedComPtr<IShellLink> i_shell_link; |
362 if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, | 346 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, |
363 CLSCTX_INPROC_SERVER, IID_IShellLink, | 347 CLSCTX_INPROC_SERVER))) |
364 reinterpret_cast<LPVOID*>(&i_shell_link)))) | |
365 return false; | 348 return false; |
366 | 349 |
367 IPersistFile *i_persist_file = NULL; | 350 ScopedComPtr<IPersistFile> i_persist_file; |
368 if (FAILED(i_shell_link->QueryInterface( | 351 if (FAILED(i_persist_file.QueryFrom(i_shell_link))) |
369 IID_IPersistFile, reinterpret_cast<LPVOID*>(&i_persist_file)))) { | |
370 i_shell_link->Release(); | |
371 return false; | 352 return false; |
372 } | |
373 | 353 |
374 if (FAILED(i_persist_file->Load(destination, 0))) { | 354 if (FAILED(i_persist_file->Load(destination, 0))) |
375 i_persist_file->Release(); | |
376 i_shell_link->Release(); | |
377 return false; | 355 return false; |
378 } | |
379 | 356 |
380 if (source && FAILED(i_shell_link->SetPath(source))) { | 357 if (source && FAILED(i_shell_link->SetPath(source))) |
381 i_persist_file->Release(); | |
382 i_shell_link->Release(); | |
383 return false; | 358 return false; |
384 } | |
385 | 359 |
386 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) { | 360 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) |
387 i_persist_file->Release(); | |
388 i_shell_link->Release(); | |
389 return false; | 361 return false; |
390 } | |
391 | 362 |
392 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) { | 363 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) |
393 i_persist_file->Release(); | |
394 i_shell_link->Release(); | |
395 return false; | 364 return false; |
396 } | |
397 | 365 |
398 if (description && FAILED(i_shell_link->SetDescription(description))) { | 366 if (description && FAILED(i_shell_link->SetDescription(description))) |
399 i_persist_file->Release(); | |
400 i_shell_link->Release(); | |
401 return false; | 367 return false; |
402 } | |
403 | 368 |
404 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) { | 369 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) |
405 i_persist_file->Release(); | |
406 i_shell_link->Release(); | |
407 return false; | 370 return false; |
| 371 |
| 372 if (app_id && win_util::GetWinVersion() >= win_util::WINVERSION_WIN7) { |
| 373 ScopedComPtr<IPropertyStore> property_store; |
| 374 if (FAILED(property_store.QueryFrom(i_shell_link))) |
| 375 return false; |
| 376 |
| 377 if (!win_util::SetAppIdForPropertyStore(property_store, app_id)) |
| 378 return false; |
408 } | 379 } |
409 | 380 |
410 HRESULT result = i_persist_file->Save(destination, TRUE); | 381 HRESULT result = i_persist_file->Save(destination, TRUE); |
411 i_persist_file->Release(); | |
412 i_shell_link->Release(); | |
413 return SUCCEEDED(result); | 382 return SUCCEEDED(result); |
414 } | 383 } |
415 | 384 |
416 bool TaskbarPinShortcutLink(const wchar_t* shortcut) { | 385 bool TaskbarPinShortcutLink(const wchar_t* shortcut) { |
417 // "Pin to taskbar" is only supported after Win7. | 386 // "Pin to taskbar" is only supported after Win7. |
418 if (win_util::GetWinVersion() < win_util::WINVERSION_WIN7) | 387 if (win_util::GetWinVersion() < win_util::WINVERSION_WIN7) |
419 return false; | 388 return false; |
420 | 389 |
421 int result = reinterpret_cast<int>(ShellExecute(NULL, L"taskbarpin", shortcut, | 390 int result = reinterpret_cast<int>(ShellExecute(NULL, L"taskbarpin", shortcut, |
422 NULL, NULL, 0)); | 391 NULL, NULL, 0)); |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 ::CloseHandle(file_mapping_); | 787 ::CloseHandle(file_mapping_); |
819 if (file_ != INVALID_HANDLE_VALUE) | 788 if (file_ != INVALID_HANDLE_VALUE) |
820 ::CloseHandle(file_); | 789 ::CloseHandle(file_); |
821 | 790 |
822 data_ = NULL; | 791 data_ = NULL; |
823 file_mapping_ = file_ = INVALID_HANDLE_VALUE; | 792 file_mapping_ = file_ = INVALID_HANDLE_VALUE; |
824 length_ = INVALID_FILE_SIZE; | 793 length_ = INVALID_FILE_SIZE; |
825 } | 794 } |
826 | 795 |
827 } // namespace file_util | 796 } // namespace file_util |
OLD | NEW |