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

Side by Side Diff: base/file_util_win.cc

Issue 105293002: Move more file_util functions to base namespace. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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
« no previous file with comments | « base/file_util_unittest.cc ('k') | base/files/file_path_watcher_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <psapi.h> 8 #include <psapi.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <shlobj.h> 10 #include <shlobj.h>
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 bool DeleteFile(const FilePath& path, bool recursive) { 85 bool DeleteFile(const FilePath& path, bool recursive) {
86 ThreadRestrictions::AssertIOAllowed(); 86 ThreadRestrictions::AssertIOAllowed();
87 87
88 if (path.value().length() >= MAX_PATH) 88 if (path.value().length() >= MAX_PATH)
89 return false; 89 return false;
90 90
91 if (!recursive) { 91 if (!recursive) {
92 // If not recursing, then first check to see if |path| is a directory. 92 // If not recursing, then first check to see if |path| is a directory.
93 // If it is, then remove it with RemoveDirectory. 93 // If it is, then remove it with RemoveDirectory.
94 PlatformFileInfo file_info; 94 PlatformFileInfo file_info;
95 if (file_util::GetFileInfo(path, &file_info) && file_info.is_directory) 95 if (GetFileInfo(path, &file_info) && file_info.is_directory)
96 return RemoveDirectory(path.value().c_str()) != 0; 96 return RemoveDirectory(path.value().c_str()) != 0;
97 97
98 // Otherwise, it's a file, wildcard or non-existant. Try DeleteFile first 98 // Otherwise, it's a file, wildcard or non-existant. Try DeleteFile first
99 // because it should be faster. If DeleteFile fails, then we fall through 99 // because it should be faster. If DeleteFile fails, then we fall through
100 // to SHFileOperation, which will do the right thing. 100 // to SHFileOperation, which will do the right thing.
101 if (::DeleteFile(path.value().c_str()) != 0) 101 if (::DeleteFile(path.value().c_str()) != 0)
102 return true; 102 return true;
103 } 103 }
104 104
105 // SHFILEOPSTRUCT wants the path to be terminated with two NULLs, 105 // SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 return false; 386 return false;
387 } 387 }
388 } else { 388 } else {
389 return true; 389 return true;
390 } 390 }
391 } 391 }
392 392
393 bool NormalizeFilePath(const FilePath& path, FilePath* real_path) { 393 bool NormalizeFilePath(const FilePath& path, FilePath* real_path) {
394 ThreadRestrictions::AssertIOAllowed(); 394 ThreadRestrictions::AssertIOAllowed();
395 FilePath mapped_file; 395 FilePath mapped_file;
396 if (!file_util::NormalizeToNativeFilePath(path, &mapped_file)) 396 if (!NormalizeToNativeFilePath(path, &mapped_file))
397 return false; 397 return false;
398 // NormalizeToNativeFilePath() will return a path that starts with 398 // NormalizeToNativeFilePath() will return a path that starts with
399 // "\Device\Harddisk...". Helper DevicePathToDriveLetterPath() 399 // "\Device\Harddisk...". Helper DevicePathToDriveLetterPath()
400 // will find a drive letter which maps to the path's device, so 400 // will find a drive letter which maps to the path's device, so
401 // that we return a path starting with a drive letter. 401 // that we return a path starting with a drive letter.
402 return file_util::DevicePathToDriveLetterPath(mapped_file, real_path); 402 return DevicePathToDriveLetterPath(mapped_file, real_path);
403 } 403 }
404 404
405 } // namespace base 405 bool DevicePathToDriveLetterPath(const FilePath& nt_device_path,
406 FilePath* out_drive_letter_path) {
407 ThreadRestrictions::AssertIOAllowed();
406 408
407 // ----------------------------------------------------------------------------- 409 // Get the mapping of drive letters to device paths.
410 const int kDriveMappingSize = 1024;
411 wchar_t drive_mapping[kDriveMappingSize] = {'\0'};
412 if (!::GetLogicalDriveStrings(kDriveMappingSize - 1, drive_mapping)) {
413 DLOG(ERROR) << "Failed to get drive mapping.";
414 return false;
415 }
408 416
409 namespace file_util { 417 // The drive mapping is a sequence of null terminated strings.
418 // The last string is empty.
419 wchar_t* drive_map_ptr = drive_mapping;
420 wchar_t device_path_as_string[MAX_PATH];
421 wchar_t drive[] = L" :";
410 422
411 using base::DirectoryExists; 423 // For each string in the drive mapping, get the junction that links
412 using base::FilePath; 424 // to it. If that junction is a prefix of |device_path|, then we
413 using base::kFileShareAll; 425 // know that |drive| is the real path prefix.
426 while (*drive_map_ptr) {
427 drive[0] = drive_map_ptr[0]; // Copy the drive letter.
428
429 if (QueryDosDevice(drive, device_path_as_string, MAX_PATH)) {
430 FilePath device_path(device_path_as_string);
431 if (device_path == nt_device_path ||
432 device_path.IsParent(nt_device_path)) {
433 *out_drive_letter_path = FilePath(drive +
434 nt_device_path.value().substr(wcslen(device_path_as_string)));
435 return true;
436 }
437 }
438 // Move to the next drive letter string, which starts one
439 // increment after the '\0' that terminates the current string.
440 while (*drive_map_ptr++);
441 }
442
443 // No drive matched. The path does not start with a device junction
444 // that is mounted as a drive letter. This means there is no drive
445 // letter path to the volume that holds |device_path|, so fail.
446 return false;
447 }
448
449 bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) {
450 ThreadRestrictions::AssertIOAllowed();
451 // In Vista, GetFinalPathNameByHandle() would give us the real path
452 // from a file handle. If we ever deprecate XP, consider changing the
453 // code below to a call to GetFinalPathNameByHandle(). The method this
454 // function uses is explained in the following msdn article:
455 // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
456 base::win::ScopedHandle file_handle(
457 ::CreateFile(path.value().c_str(),
458 GENERIC_READ,
459 kFileShareAll,
460 NULL,
461 OPEN_EXISTING,
462 FILE_ATTRIBUTE_NORMAL,
463 NULL));
464 if (!file_handle)
465 return false;
466
467 // Create a file mapping object. Can't easily use MemoryMappedFile, because
468 // we only map the first byte, and need direct access to the handle. You can
469 // not map an empty file, this call fails in that case.
470 base::win::ScopedHandle file_map_handle(
471 ::CreateFileMapping(file_handle.Get(),
472 NULL,
473 PAGE_READONLY,
474 0,
475 1, // Just one byte. No need to look at the data.
476 NULL));
477 if (!file_map_handle)
478 return false;
479
480 // Use a view of the file to get the path to the file.
481 void* file_view = MapViewOfFile(file_map_handle.Get(),
482 FILE_MAP_READ, 0, 0, 1);
483 if (!file_view)
484 return false;
485
486 // The expansion of |path| into a full path may make it longer.
487 // GetMappedFileName() will fail if the result is longer than MAX_PATH.
488 // Pad a bit to be safe. If kMaxPathLength is ever changed to be less
489 // than MAX_PATH, it would be nessisary to test that GetMappedFileName()
490 // not return kMaxPathLength. This would mean that only part of the
491 // path fit in |mapped_file_path|.
492 const int kMaxPathLength = MAX_PATH + 10;
493 wchar_t mapped_file_path[kMaxPathLength];
494 bool success = false;
495 HANDLE cp = GetCurrentProcess();
496 if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) {
497 *nt_path = FilePath(mapped_file_path);
498 success = true;
499 }
500 ::UnmapViewOfFile(file_view);
501 return success;
502 }
414 503
415 // TODO(rkc): Work out if we want to handle NTFS junctions here or not, handle 504 // TODO(rkc): Work out if we want to handle NTFS junctions here or not, handle
416 // them if we do decide to. 505 // them if we do decide to.
417 bool IsLink(const FilePath& file_path) { 506 bool IsLink(const FilePath& file_path) {
418 return false; 507 return false;
419 } 508 }
420 509
421 bool GetFileInfo(const FilePath& file_path, base::PlatformFileInfo* results) { 510 bool GetFileInfo(const FilePath& file_path, PlatformFileInfo* results) {
422 base::ThreadRestrictions::AssertIOAllowed(); 511 ThreadRestrictions::AssertIOAllowed();
423 512
424 WIN32_FILE_ATTRIBUTE_DATA attr; 513 WIN32_FILE_ATTRIBUTE_DATA attr;
425 if (!GetFileAttributesEx(file_path.value().c_str(), 514 if (!GetFileAttributesEx(file_path.value().c_str(),
426 GetFileExInfoStandard, &attr)) { 515 GetFileExInfoStandard, &attr)) {
427 return false; 516 return false;
428 } 517 }
429 518
430 ULARGE_INTEGER size; 519 ULARGE_INTEGER size;
431 size.HighPart = attr.nFileSizeHigh; 520 size.HighPart = attr.nFileSizeHigh;
432 size.LowPart = attr.nFileSizeLow; 521 size.LowPart = attr.nFileSizeLow;
433 results->size = size.QuadPart; 522 results->size = size.QuadPart;
434 523
435 results->is_directory = 524 results->is_directory =
436 (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; 525 (attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
437 results->last_modified = base::Time::FromFileTime(attr.ftLastWriteTime); 526 results->last_modified = Time::FromFileTime(attr.ftLastWriteTime);
438 results->last_accessed = base::Time::FromFileTime(attr.ftLastAccessTime); 527 results->last_accessed = Time::FromFileTime(attr.ftLastAccessTime);
439 results->creation_time = base::Time::FromFileTime(attr.ftCreationTime); 528 results->creation_time = Time::FromFileTime(attr.ftCreationTime);
440 529
441 return true; 530 return true;
442 } 531 }
443 532
533 } // namespace base
534
535 // -----------------------------------------------------------------------------
536
537 namespace file_util {
538
539 using base::DirectoryExists;
540 using base::FilePath;
541 using base::kFileShareAll;
542
444 FILE* OpenFile(const FilePath& filename, const char* mode) { 543 FILE* OpenFile(const FilePath& filename, const char* mode) {
445 base::ThreadRestrictions::AssertIOAllowed(); 544 base::ThreadRestrictions::AssertIOAllowed();
446 std::wstring w_mode = ASCIIToWide(std::string(mode)); 545 std::wstring w_mode = ASCIIToWide(std::string(mode));
447 return _wfsopen(filename.value().c_str(), w_mode.c_str(), _SH_DENYNO); 546 return _wfsopen(filename.value().c_str(), w_mode.c_str(), _SH_DENYNO);
448 } 547 }
449 548
450 FILE* OpenFile(const std::string& filename, const char* mode) { 549 FILE* OpenFile(const std::string& filename, const char* mode) {
451 base::ThreadRestrictions::AssertIOAllowed(); 550 base::ThreadRestrictions::AssertIOAllowed();
452 return _fsopen(filename.c_str(), mode, _SH_DENYNO); 551 return _fsopen(filename.c_str(), mode, _SH_DENYNO);
453 } 552 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 return true; 651 return true;
553 } 652 }
554 653
555 // Sets the current working directory for the process. 654 // Sets the current working directory for the process.
556 bool SetCurrentDirectory(const FilePath& directory) { 655 bool SetCurrentDirectory(const FilePath& directory) {
557 base::ThreadRestrictions::AssertIOAllowed(); 656 base::ThreadRestrictions::AssertIOAllowed();
558 BOOL ret = ::SetCurrentDirectory(directory.value().c_str()); 657 BOOL ret = ::SetCurrentDirectory(directory.value().c_str());
559 return ret != 0; 658 return ret != 0;
560 } 659 }
561 660
562 bool DevicePathToDriveLetterPath(const FilePath& nt_device_path,
563 FilePath* out_drive_letter_path) {
564 base::ThreadRestrictions::AssertIOAllowed();
565
566 // Get the mapping of drive letters to device paths.
567 const int kDriveMappingSize = 1024;
568 wchar_t drive_mapping[kDriveMappingSize] = {'\0'};
569 if (!::GetLogicalDriveStrings(kDriveMappingSize - 1, drive_mapping)) {
570 DLOG(ERROR) << "Failed to get drive mapping.";
571 return false;
572 }
573
574 // The drive mapping is a sequence of null terminated strings.
575 // The last string is empty.
576 wchar_t* drive_map_ptr = drive_mapping;
577 wchar_t device_path_as_string[MAX_PATH];
578 wchar_t drive[] = L" :";
579
580 // For each string in the drive mapping, get the junction that links
581 // to it. If that junction is a prefix of |device_path|, then we
582 // know that |drive| is the real path prefix.
583 while (*drive_map_ptr) {
584 drive[0] = drive_map_ptr[0]; // Copy the drive letter.
585
586 if (QueryDosDevice(drive, device_path_as_string, MAX_PATH)) {
587 FilePath device_path(device_path_as_string);
588 if (device_path == nt_device_path ||
589 device_path.IsParent(nt_device_path)) {
590 *out_drive_letter_path = FilePath(drive +
591 nt_device_path.value().substr(wcslen(device_path_as_string)));
592 return true;
593 }
594 }
595 // Move to the next drive letter string, which starts one
596 // increment after the '\0' that terminates the current string.
597 while (*drive_map_ptr++);
598 }
599
600 // No drive matched. The path does not start with a device junction
601 // that is mounted as a drive letter. This means there is no drive
602 // letter path to the volume that holds |device_path|, so fail.
603 return false;
604 }
605
606 bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) {
607 base::ThreadRestrictions::AssertIOAllowed();
608 // In Vista, GetFinalPathNameByHandle() would give us the real path
609 // from a file handle. If we ever deprecate XP, consider changing the
610 // code below to a call to GetFinalPathNameByHandle(). The method this
611 // function uses is explained in the following msdn article:
612 // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
613 base::win::ScopedHandle file_handle(
614 ::CreateFile(path.value().c_str(),
615 GENERIC_READ,
616 kFileShareAll,
617 NULL,
618 OPEN_EXISTING,
619 FILE_ATTRIBUTE_NORMAL,
620 NULL));
621 if (!file_handle)
622 return false;
623
624 // Create a file mapping object. Can't easily use MemoryMappedFile, because
625 // we only map the first byte, and need direct access to the handle. You can
626 // not map an empty file, this call fails in that case.
627 base::win::ScopedHandle file_map_handle(
628 ::CreateFileMapping(file_handle.Get(),
629 NULL,
630 PAGE_READONLY,
631 0,
632 1, // Just one byte. No need to look at the data.
633 NULL));
634 if (!file_map_handle)
635 return false;
636
637 // Use a view of the file to get the path to the file.
638 void* file_view = MapViewOfFile(file_map_handle.Get(),
639 FILE_MAP_READ, 0, 0, 1);
640 if (!file_view)
641 return false;
642
643 // The expansion of |path| into a full path may make it longer.
644 // GetMappedFileName() will fail if the result is longer than MAX_PATH.
645 // Pad a bit to be safe. If kMaxPathLength is ever changed to be less
646 // than MAX_PATH, it would be nessisary to test that GetMappedFileName()
647 // not return kMaxPathLength. This would mean that only part of the
648 // path fit in |mapped_file_path|.
649 const int kMaxPathLength = MAX_PATH + 10;
650 wchar_t mapped_file_path[kMaxPathLength];
651 bool success = false;
652 HANDLE cp = GetCurrentProcess();
653 if (::GetMappedFileNameW(cp, file_view, mapped_file_path, kMaxPathLength)) {
654 *nt_path = FilePath(mapped_file_path);
655 success = true;
656 }
657 ::UnmapViewOfFile(file_view);
658 return success;
659 }
660
661 int GetMaximumPathComponentLength(const FilePath& path) { 661 int GetMaximumPathComponentLength(const FilePath& path) {
662 base::ThreadRestrictions::AssertIOAllowed(); 662 base::ThreadRestrictions::AssertIOAllowed();
663 663
664 wchar_t volume_path[MAX_PATH]; 664 wchar_t volume_path[MAX_PATH];
665 if (!GetVolumePathNameW(path.NormalizePathSeparators().value().c_str(), 665 if (!GetVolumePathNameW(path.NormalizePathSeparators().value().c_str(),
666 volume_path, 666 volume_path,
667 arraysize(volume_path))) { 667 arraysize(volume_path))) {
668 return -1; 668 return -1;
669 } 669 }
670 670
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 // Like Move, this function is not transactional, so we just 744 // Like Move, this function is not transactional, so we just
745 // leave the copied bits behind if deleting from_path fails. 745 // leave the copied bits behind if deleting from_path fails.
746 // If to_path exists previously then we have already overwritten 746 // If to_path exists previously then we have already overwritten
747 // it by now, we don't get better off by deleting the new bits. 747 // it by now, we don't get better off by deleting the new bits.
748 } 748 }
749 return false; 749 return false;
750 } 750 }
751 751
752 } // namespace internal 752 } // namespace internal
753 } // namespace base 753 } // namespace base
OLDNEW
« no previous file with comments | « base/file_util_unittest.cc ('k') | base/files/file_path_watcher_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698