Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(721)

Side by Side Diff: base/file_util_win.cc

Issue 3781009: Move the windows-specific scoped_* stuff from base to base/win and in the bas... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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>
11 #include <shlobj.h> 11 #include <shlobj.h>
12 #include <time.h> 12 #include <time.h>
13 #include <string> 13 #include <string>
14 14
15 #include "base/file_path.h" 15 #include "base/file_path.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/pe_image.h" 18 #include "base/pe_image.h"
19 #include "base/scoped_comptr_win.h" 19 #include "base/win/scoped_handle.h"
20 #include "base/scoped_handle.h"
21 #include "base/string_number_conversions.h" 20 #include "base/string_number_conversions.h"
22 #include "base/string_util.h" 21 #include "base/string_util.h"
23 #include "base/time.h" 22 #include "base/time.h"
24 #include "base/utf_string_conversions.h" 23 #include "base/utf_string_conversions.h"
25 #include "base/win_util.h" 24 #include "base/win_util.h"
25 #include "base/win/scoped_comptr.h"
26 #include "base/win/windows_version.h" 26 #include "base/win/windows_version.h"
27 27
28 namespace file_util { 28 namespace file_util {
29 29
30 namespace { 30 namespace {
31 31
32 const DWORD kFileShareAll = 32 const DWORD kFileShareAll =
33 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 33 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
34 34
35 // Helper for NormalizeFilePath(), defined below. 35 // Helper for NormalizeFilePath(), defined below.
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 321
322 FILETIME local_filetime; 322 FILETIME local_filetime;
323 if (!FileTimeToLocalFileTime(&utc_filetime, &local_filetime)) 323 if (!FileTimeToLocalFileTime(&utc_filetime, &local_filetime))
324 return false; 324 return false;
325 325
326 return !!FileTimeToSystemTime(&local_filetime, creation_time); 326 return !!FileTimeToSystemTime(&local_filetime, creation_time);
327 } 327 }
328 328
329 bool GetFileCreationLocalTime(const std::wstring& filename, 329 bool GetFileCreationLocalTime(const std::wstring& filename,
330 LPSYSTEMTIME creation_time) { 330 LPSYSTEMTIME creation_time) {
331 ScopedHandle file_handle( 331 base::win::ScopedHandle file_handle(
332 CreateFile(filename.c_str(), GENERIC_READ, kFileShareAll, NULL, 332 CreateFile(filename.c_str(), GENERIC_READ, kFileShareAll, NULL,
333 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); 333 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
334 return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time); 334 return GetFileCreationLocalTimeFromHandle(file_handle.Get(), creation_time);
335 } 335 }
336 336
337 bool ResolveShortcut(FilePath* path) { 337 bool ResolveShortcut(FilePath* path) {
338 HRESULT result; 338 HRESULT result;
339 ScopedComPtr<IShellLink> i_shell_link; 339 base::win::ScopedComPtr<IShellLink> i_shell_link;
340 bool is_resolved = false; 340 bool is_resolved = false;
341 341
342 // Get pointer to the IShellLink interface 342 // Get pointer to the IShellLink interface
343 result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, 343 result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
344 CLSCTX_INPROC_SERVER); 344 CLSCTX_INPROC_SERVER);
345 if (SUCCEEDED(result)) { 345 if (SUCCEEDED(result)) {
346 ScopedComPtr<IPersistFile> persist; 346 base::win::ScopedComPtr<IPersistFile> persist;
347 // Query IShellLink for the IPersistFile interface 347 // Query IShellLink for the IPersistFile interface
348 result = persist.QueryFrom(i_shell_link); 348 result = persist.QueryFrom(i_shell_link);
349 if (SUCCEEDED(result)) { 349 if (SUCCEEDED(result)) {
350 WCHAR temp_path[MAX_PATH]; 350 WCHAR temp_path[MAX_PATH];
351 // Load the shell link 351 // Load the shell link
352 result = persist->Load(path->value().c_str(), STGM_READ); 352 result = persist->Load(path->value().c_str(), STGM_READ);
353 if (SUCCEEDED(result)) { 353 if (SUCCEEDED(result)) {
354 // Try to find the target of a shortcut 354 // Try to find the target of a shortcut
355 result = i_shell_link->Resolve(0, SLR_NO_UI); 355 result = i_shell_link->Resolve(0, SLR_NO_UI);
356 if (SUCCEEDED(result)) { 356 if (SUCCEEDED(result)) {
(...skipping 10 matching lines...) Expand all
367 } 367 }
368 368
369 bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination, 369 bool CreateShortcutLink(const wchar_t *source, const wchar_t *destination,
370 const wchar_t *working_dir, const wchar_t *arguments, 370 const wchar_t *working_dir, const wchar_t *arguments,
371 const wchar_t *description, const wchar_t *icon, 371 const wchar_t *description, const wchar_t *icon,
372 int icon_index, const wchar_t* app_id) { 372 int icon_index, const wchar_t* app_id) {
373 // Length of arguments and description must be less than MAX_PATH. 373 // Length of arguments and description must be less than MAX_PATH.
374 DCHECK(lstrlen(arguments) < MAX_PATH); 374 DCHECK(lstrlen(arguments) < MAX_PATH);
375 DCHECK(lstrlen(description) < MAX_PATH); 375 DCHECK(lstrlen(description) < MAX_PATH);
376 376
377 ScopedComPtr<IShellLink> i_shell_link; 377 base::win::ScopedComPtr<IShellLink> i_shell_link;
378 ScopedComPtr<IPersistFile> i_persist_file; 378 base::win::ScopedComPtr<IPersistFile> i_persist_file;
379 379
380 // Get pointer to the IShellLink interface 380 // Get pointer to the IShellLink interface
381 HRESULT result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, 381 HRESULT result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
382 CLSCTX_INPROC_SERVER); 382 CLSCTX_INPROC_SERVER);
383 if (FAILED(result)) 383 if (FAILED(result))
384 return false; 384 return false;
385 385
386 // Query IShellLink for the IPersistFile interface 386 // Query IShellLink for the IPersistFile interface
387 result = i_persist_file.QueryFrom(i_shell_link); 387 result = i_persist_file.QueryFrom(i_shell_link);
388 if (FAILED(result)) 388 if (FAILED(result))
389 return false; 389 return false;
390 390
391 if (FAILED(i_shell_link->SetPath(source))) 391 if (FAILED(i_shell_link->SetPath(source)))
392 return false; 392 return false;
393 393
394 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) 394 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir)))
395 return false; 395 return false;
396 396
397 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) 397 if (arguments && FAILED(i_shell_link->SetArguments(arguments)))
398 return false; 398 return false;
399 399
400 if (description && FAILED(i_shell_link->SetDescription(description))) 400 if (description && FAILED(i_shell_link->SetDescription(description)))
401 return false; 401 return false;
402 402
403 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) 403 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index)))
404 return false; 404 return false;
405 405
406 if (app_id && (base::win::GetVersion() >= base::win::VERSION_WIN7)) { 406 if (app_id && (base::win::GetVersion() >= base::win::VERSION_WIN7)) {
407 ScopedComPtr<IPropertyStore> property_store; 407 base::win::ScopedComPtr<IPropertyStore> property_store;
408 if (FAILED(property_store.QueryFrom(i_shell_link))) 408 if (FAILED(property_store.QueryFrom(i_shell_link)))
409 return false; 409 return false;
410 410
411 if (!win_util::SetAppIdForPropertyStore(property_store, app_id)) 411 if (!win_util::SetAppIdForPropertyStore(property_store, app_id))
412 return false; 412 return false;
413 } 413 }
414 414
415 result = i_persist_file->Save(destination, TRUE); 415 result = i_persist_file->Save(destination, TRUE);
416 return SUCCEEDED(result); 416 return SUCCEEDED(result);
417 } 417 }
418 418
419 419
420 bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination, 420 bool UpdateShortcutLink(const wchar_t *source, const wchar_t *destination,
421 const wchar_t *working_dir, const wchar_t *arguments, 421 const wchar_t *working_dir, const wchar_t *arguments,
422 const wchar_t *description, const wchar_t *icon, 422 const wchar_t *description, const wchar_t *icon,
423 int icon_index, const wchar_t* app_id) { 423 int icon_index, const wchar_t* app_id) {
424 // Length of arguments and description must be less than MAX_PATH. 424 // Length of arguments and description must be less than MAX_PATH.
425 DCHECK(lstrlen(arguments) < MAX_PATH); 425 DCHECK(lstrlen(arguments) < MAX_PATH);
426 DCHECK(lstrlen(description) < MAX_PATH); 426 DCHECK(lstrlen(description) < MAX_PATH);
427 427
428 // Get pointer to the IPersistFile interface and load existing link 428 // Get pointer to the IPersistFile interface and load existing link
429 ScopedComPtr<IShellLink> i_shell_link; 429 base::win::ScopedComPtr<IShellLink> i_shell_link;
430 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL, 430 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
431 CLSCTX_INPROC_SERVER))) 431 CLSCTX_INPROC_SERVER)))
432 return false; 432 return false;
433 433
434 ScopedComPtr<IPersistFile> i_persist_file; 434 base::win::ScopedComPtr<IPersistFile> i_persist_file;
435 if (FAILED(i_persist_file.QueryFrom(i_shell_link))) 435 if (FAILED(i_persist_file.QueryFrom(i_shell_link)))
436 return false; 436 return false;
437 437
438 if (FAILED(i_persist_file->Load(destination, STGM_READWRITE))) 438 if (FAILED(i_persist_file->Load(destination, STGM_READWRITE)))
439 return false; 439 return false;
440 440
441 if (source && FAILED(i_shell_link->SetPath(source))) 441 if (source && FAILED(i_shell_link->SetPath(source)))
442 return false; 442 return false;
443 443
444 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir))) 444 if (working_dir && FAILED(i_shell_link->SetWorkingDirectory(working_dir)))
445 return false; 445 return false;
446 446
447 if (arguments && FAILED(i_shell_link->SetArguments(arguments))) 447 if (arguments && FAILED(i_shell_link->SetArguments(arguments)))
448 return false; 448 return false;
449 449
450 if (description && FAILED(i_shell_link->SetDescription(description))) 450 if (description && FAILED(i_shell_link->SetDescription(description)))
451 return false; 451 return false;
452 452
453 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index))) 453 if (icon && FAILED(i_shell_link->SetIconLocation(icon, icon_index)))
454 return false; 454 return false;
455 455
456 if (app_id && base::win::GetVersion() >= base::win::VERSION_WIN7) { 456 if (app_id && base::win::GetVersion() >= base::win::VERSION_WIN7) {
457 ScopedComPtr<IPropertyStore> property_store; 457 base::win::ScopedComPtr<IPropertyStore> property_store;
458 if (FAILED(property_store.QueryFrom(i_shell_link))) 458 if (FAILED(property_store.QueryFrom(i_shell_link)))
459 return false; 459 return false;
460 460
461 if (!win_util::SetAppIdForPropertyStore(property_store, app_id)) 461 if (!win_util::SetAppIdForPropertyStore(property_store, app_id))
462 return false; 462 return false;
463 } 463 }
464 464
465 HRESULT result = i_persist_file->Save(destination, TRUE); 465 HRESULT result = i_persist_file->Save(destination, TRUE);
466 return SUCCEEDED(result); 466 return SUCCEEDED(result);
467 } 467 }
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 FILE* OpenFile(const FilePath& filename, const char* mode) { 665 FILE* OpenFile(const FilePath& filename, const char* mode) {
666 std::wstring w_mode = ASCIIToWide(std::string(mode)); 666 std::wstring w_mode = ASCIIToWide(std::string(mode));
667 return _wfsopen(filename.value().c_str(), w_mode.c_str(), _SH_DENYNO); 667 return _wfsopen(filename.value().c_str(), w_mode.c_str(), _SH_DENYNO);
668 } 668 }
669 669
670 FILE* OpenFile(const std::string& filename, const char* mode) { 670 FILE* OpenFile(const std::string& filename, const char* mode) {
671 return _fsopen(filename.c_str(), mode, _SH_DENYNO); 671 return _fsopen(filename.c_str(), mode, _SH_DENYNO);
672 } 672 }
673 673
674 int ReadFile(const FilePath& filename, char* data, int size) { 674 int ReadFile(const FilePath& filename, char* data, int size) {
675 ScopedHandle file(CreateFile(filename.value().c_str(), 675 base::win::ScopedHandle file(CreateFile(filename.value().c_str(),
676 GENERIC_READ, 676 GENERIC_READ,
677 FILE_SHARE_READ | FILE_SHARE_WRITE, 677 FILE_SHARE_READ | FILE_SHARE_WRITE,
678 NULL, 678 NULL,
679 OPEN_EXISTING, 679 OPEN_EXISTING,
680 FILE_FLAG_SEQUENTIAL_SCAN, 680 FILE_FLAG_SEQUENTIAL_SCAN,
681 NULL)); 681 NULL));
682 if (!file) 682 if (!file)
683 return -1; 683 return -1;
684 684
685 DWORD read; 685 DWORD read;
686 if (::ReadFile(file, data, size, &read, NULL) && 686 if (::ReadFile(file, data, size, &read, NULL) &&
687 static_cast<int>(read) == size) 687 static_cast<int>(read) == size)
688 return read; 688 return read;
689 return -1; 689 return -1;
690 } 690 }
691 691
692 int WriteFile(const FilePath& filename, const char* data, int size) { 692 int WriteFile(const FilePath& filename, const char* data, int size) {
693 ScopedHandle file(CreateFile(filename.value().c_str(), 693 base::win::ScopedHandle file(CreateFile(filename.value().c_str(),
694 GENERIC_WRITE, 694 GENERIC_WRITE,
695 0, 695 0,
696 NULL, 696 NULL,
697 CREATE_ALWAYS, 697 CREATE_ALWAYS,
698 0, 698 0,
699 NULL)); 699 NULL));
700 if (!file) { 700 if (!file) {
701 LOG(WARNING) << "CreateFile failed for path " << filename.value() << 701 LOG(WARNING) << "CreateFile failed for path " << filename.value() <<
702 " error code=" << GetLastError() << 702 " error code=" << GetLastError() <<
703 " error text=" << win_util::FormatLastWin32Error(); 703 " error text=" << win_util::FormatLastWin32Error();
704 return -1; 704 return -1;
705 } 705 }
706 706
707 DWORD written; 707 DWORD written;
708 BOOL result = ::WriteFile(file, data, size, &written, NULL); 708 BOOL result = ::WriteFile(file, data, size, &written, NULL);
709 if (result && static_cast<int>(written) == size) 709 if (result && static_cast<int>(written) == size)
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 // that we return a path starting with a drive letter. 951 // that we return a path starting with a drive letter.
952 return DevicePathToDriveLetterPath(mapped_file, real_path); 952 return DevicePathToDriveLetterPath(mapped_file, real_path);
953 } 953 }
954 954
955 bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) { 955 bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) {
956 // In Vista, GetFinalPathNameByHandle() would give us the real path 956 // In Vista, GetFinalPathNameByHandle() would give us the real path
957 // from a file handle. If we ever deprecate XP, consider changing the 957 // from a file handle. If we ever deprecate XP, consider changing the
958 // code below to a call to GetFinalPathNameByHandle(). The method this 958 // code below to a call to GetFinalPathNameByHandle(). The method this
959 // function uses is explained in the following msdn article: 959 // function uses is explained in the following msdn article:
960 // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx 960 // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
961 ScopedHandle file_handle( 961 base::win::ScopedHandle file_handle(
962 ::CreateFile(path.value().c_str(), 962 ::CreateFile(path.value().c_str(),
963 GENERIC_READ, 963 GENERIC_READ,
964 kFileShareAll, 964 kFileShareAll,
965 NULL, 965 NULL,
966 OPEN_EXISTING, 966 OPEN_EXISTING,
967 FILE_ATTRIBUTE_NORMAL, 967 FILE_ATTRIBUTE_NORMAL,
968 NULL)); 968 NULL));
969 if (!file_handle) 969 if (!file_handle)
970 return false; 970 return false;
971 971
972 // Create a file mapping object. Can't easily use MemoryMappedFile, because 972 // Create a file mapping object. Can't easily use MemoryMappedFile, because
973 // we only map the first byte, and need direct access to the handle. You can 973 // we only map the first byte, and need direct access to the handle. You can
974 // not map an empty file, this call fails in that case. 974 // not map an empty file, this call fails in that case.
975 ScopedHandle file_map_handle( 975 base::win::ScopedHandle file_map_handle(
976 ::CreateFileMapping(file_handle.Get(), 976 ::CreateFileMapping(file_handle.Get(),
977 NULL, 977 NULL,
978 PAGE_READONLY, 978 PAGE_READONLY,
979 0, 979 0,
980 1, // Just one byte. No need to look at the data. 980 1, // Just one byte. No need to look at the data.
981 NULL)); 981 NULL));
982 if (!file_map_handle) 982 if (!file_map_handle)
983 return false; 983 return false;
984 984
985 // Use a view of the file to get the path to the file. 985 // Use a view of the file to get the path to the file.
(...skipping 19 matching lines...) Expand all
1005 ::UnmapViewOfFile(file_view); 1005 ::UnmapViewOfFile(file_view);
1006 return success; 1006 return success;
1007 } 1007 }
1008 1008
1009 bool PreReadImage(const wchar_t* file_path, size_t size_to_read, 1009 bool PreReadImage(const wchar_t* file_path, size_t size_to_read,
1010 size_t step_size) { 1010 size_t step_size) {
1011 if (base::win::GetVersion() > base::win::VERSION_XP) { 1011 if (base::win::GetVersion() > base::win::VERSION_XP) {
1012 // Vista+ branch. On these OSes, the forced reads through the DLL actually 1012 // Vista+ branch. On these OSes, the forced reads through the DLL actually
1013 // slows warm starts. The solution is to sequentially read file contents 1013 // slows warm starts. The solution is to sequentially read file contents
1014 // with an optional cap on total amount to read. 1014 // with an optional cap on total amount to read.
1015 ScopedHandle file( 1015 base::win::ScopedHandle file(
1016 CreateFile(file_path, 1016 CreateFile(file_path,
1017 GENERIC_READ, 1017 GENERIC_READ,
1018 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 1018 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1019 NULL, 1019 NULL,
1020 OPEN_EXISTING, 1020 OPEN_EXISTING,
1021 FILE_FLAG_SEQUENTIAL_SCAN, 1021 FILE_FLAG_SEQUENTIAL_SCAN,
1022 NULL)); 1022 NULL));
1023 1023
1024 if (!file.IsValid()) 1024 if (!file.IsValid())
1025 return false; 1025 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 uint8 unused = *(touch + offset); 1065 uint8 unused = *(touch + offset);
1066 offset += step_size; 1066 offset += step_size;
1067 } 1067 }
1068 FreeLibrary(dll_module); 1068 FreeLibrary(dll_module);
1069 } 1069 }
1070 1070
1071 return true; 1071 return true;
1072 } 1072 }
1073 1073
1074 } // namespace file_util 1074 } // namespace file_util
OLDNEW
« no previous file with comments | « base/base.gypi ('k') | base/process_util_win.cc » ('j') | base/win/scoped_comptr.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698