| 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 <psapi.h> | 8 #include <psapi.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #include <shlobj.h> | 10 #include <shlobj.h> |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 return true; | 592 return true; |
| 593 } | 593 } |
| 594 | 594 |
| 595 // Sets the current working directory for the process. | 595 // Sets the current working directory for the process. |
| 596 bool SetCurrentDirectory(const FilePath& directory) { | 596 bool SetCurrentDirectory(const FilePath& directory) { |
| 597 base::ThreadRestrictions::AssertIOAllowed(); | 597 base::ThreadRestrictions::AssertIOAllowed(); |
| 598 BOOL ret = ::SetCurrentDirectory(directory.value().c_str()); | 598 BOOL ret = ::SetCurrentDirectory(directory.value().c_str()); |
| 599 return ret != 0; | 599 return ret != 0; |
| 600 } | 600 } |
| 601 | 601 |
| 602 /////////////////////////////////////////////// | |
| 603 // FileEnumerator | |
| 604 | |
| 605 FileEnumerator::FileEnumerator(const FilePath& root_path, | |
| 606 bool recursive, | |
| 607 int file_type) | |
| 608 : recursive_(recursive), | |
| 609 file_type_(file_type), | |
| 610 has_find_data_(false), | |
| 611 find_handle_(INVALID_HANDLE_VALUE) { | |
| 612 // INCLUDE_DOT_DOT must not be specified if recursive. | |
| 613 DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); | |
| 614 memset(&find_data_, 0, sizeof(find_data_)); | |
| 615 pending_paths_.push(root_path); | |
| 616 } | |
| 617 | |
| 618 FileEnumerator::FileEnumerator(const FilePath& root_path, | |
| 619 bool recursive, | |
| 620 int file_type, | |
| 621 const FilePath::StringType& pattern) | |
| 622 : recursive_(recursive), | |
| 623 file_type_(file_type), | |
| 624 has_find_data_(false), | |
| 625 pattern_(pattern), | |
| 626 find_handle_(INVALID_HANDLE_VALUE) { | |
| 627 // INCLUDE_DOT_DOT must not be specified if recursive. | |
| 628 DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); | |
| 629 memset(&find_data_, 0, sizeof(find_data_)); | |
| 630 pending_paths_.push(root_path); | |
| 631 } | |
| 632 | |
| 633 FileEnumerator::~FileEnumerator() { | |
| 634 if (find_handle_ != INVALID_HANDLE_VALUE) | |
| 635 FindClose(find_handle_); | |
| 636 } | |
| 637 | |
| 638 void FileEnumerator::GetFindInfo(FindInfo* info) { | |
| 639 DCHECK(info); | |
| 640 | |
| 641 if (!has_find_data_) | |
| 642 return; | |
| 643 | |
| 644 memcpy(info, &find_data_, sizeof(*info)); | |
| 645 } | |
| 646 | |
| 647 // static | |
| 648 bool FileEnumerator::IsDirectory(const FindInfo& info) { | |
| 649 return (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | |
| 650 } | |
| 651 | |
| 652 // static | |
| 653 FilePath FileEnumerator::GetFilename(const FindInfo& find_info) { | |
| 654 return FilePath(find_info.cFileName); | |
| 655 } | |
| 656 | |
| 657 // static | |
| 658 int64 FileEnumerator::GetFilesize(const FindInfo& find_info) { | |
| 659 ULARGE_INTEGER size; | |
| 660 size.HighPart = find_info.nFileSizeHigh; | |
| 661 size.LowPart = find_info.nFileSizeLow; | |
| 662 DCHECK_LE(size.QuadPart, std::numeric_limits<int64>::max()); | |
| 663 return static_cast<int64>(size.QuadPart); | |
| 664 } | |
| 665 | |
| 666 // static | |
| 667 base::Time FileEnumerator::GetLastModifiedTime(const FindInfo& find_info) { | |
| 668 return base::Time::FromFileTime(find_info.ftLastWriteTime); | |
| 669 } | |
| 670 | |
| 671 FilePath FileEnumerator::Next() { | |
| 672 base::ThreadRestrictions::AssertIOAllowed(); | |
| 673 | |
| 674 while (has_find_data_ || !pending_paths_.empty()) { | |
| 675 if (!has_find_data_) { | |
| 676 // The last find FindFirstFile operation is done, prepare a new one. | |
| 677 root_path_ = pending_paths_.top(); | |
| 678 pending_paths_.pop(); | |
| 679 | |
| 680 // Start a new find operation. | |
| 681 FilePath src = root_path_; | |
| 682 | |
| 683 if (pattern_.empty()) | |
| 684 src = src.Append(L"*"); // No pattern = match everything. | |
| 685 else | |
| 686 src = src.Append(pattern_); | |
| 687 | |
| 688 find_handle_ = FindFirstFile(src.value().c_str(), &find_data_); | |
| 689 has_find_data_ = true; | |
| 690 } else { | |
| 691 // Search for the next file/directory. | |
| 692 if (!FindNextFile(find_handle_, &find_data_)) { | |
| 693 FindClose(find_handle_); | |
| 694 find_handle_ = INVALID_HANDLE_VALUE; | |
| 695 } | |
| 696 } | |
| 697 | |
| 698 if (INVALID_HANDLE_VALUE == find_handle_) { | |
| 699 has_find_data_ = false; | |
| 700 | |
| 701 // This is reached when we have finished a directory and are advancing to | |
| 702 // the next one in the queue. We applied the pattern (if any) to the files | |
| 703 // in the root search directory, but for those directories which were | |
| 704 // matched, we want to enumerate all files inside them. This will happen | |
| 705 // when the handle is empty. | |
| 706 pattern_ = FilePath::StringType(); | |
| 707 | |
| 708 continue; | |
| 709 } | |
| 710 | |
| 711 FilePath cur_file(find_data_.cFileName); | |
| 712 if (ShouldSkip(cur_file)) | |
| 713 continue; | |
| 714 | |
| 715 // Construct the absolute filename. | |
| 716 cur_file = root_path_.Append(find_data_.cFileName); | |
| 717 | |
| 718 if (find_data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { | |
| 719 if (recursive_) { | |
| 720 // If |cur_file| is a directory, and we are doing recursive searching, | |
| 721 // add it to pending_paths_ so we scan it after we finish scanning this | |
| 722 // directory. | |
| 723 pending_paths_.push(cur_file); | |
| 724 } | |
| 725 if (file_type_ & FileEnumerator::DIRECTORIES) | |
| 726 return cur_file; | |
| 727 } else if (file_type_ & FileEnumerator::FILES) { | |
| 728 return cur_file; | |
| 729 } | |
| 730 } | |
| 731 | |
| 732 return FilePath(); | |
| 733 } | |
| 734 | |
| 735 bool NormalizeFilePath(const FilePath& path, FilePath* real_path) { | 602 bool NormalizeFilePath(const FilePath& path, FilePath* real_path) { |
| 736 base::ThreadRestrictions::AssertIOAllowed(); | 603 base::ThreadRestrictions::AssertIOAllowed(); |
| 737 FilePath mapped_file; | 604 FilePath mapped_file; |
| 738 if (!NormalizeToNativeFilePath(path, &mapped_file)) | 605 if (!NormalizeToNativeFilePath(path, &mapped_file)) |
| 739 return false; | 606 return false; |
| 740 // NormalizeToNativeFilePath() will return a path that starts with | 607 // NormalizeToNativeFilePath() will return a path that starts with |
| 741 // "\Device\Harddisk...". Helper DevicePathToDriveLetterPath() | 608 // "\Device\Harddisk...". Helper DevicePathToDriveLetterPath() |
| 742 // will find a drive letter which maps to the path's device, so | 609 // will find a drive letter which maps to the path's device, so |
| 743 // that we return a path starting with a drive letter. | 610 // that we return a path starting with a drive letter. |
| 744 return DevicePathToDriveLetterPath(mapped_file, real_path); | 611 return DevicePathToDriveLetterPath(mapped_file, real_path); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 | 728 |
| 862 // Length of |path| with path separator appended. | 729 // Length of |path| with path separator appended. |
| 863 size_t prefix = path.StripTrailingSeparators().value().size() + 1; | 730 size_t prefix = path.StripTrailingSeparators().value().size() + 1; |
| 864 // The whole path string must be shorter than MAX_PATH. That is, it must be | 731 // The whole path string must be shorter than MAX_PATH. That is, it must be |
| 865 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). | 732 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). |
| 866 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); | 733 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); |
| 867 return std::min(whole_path_limit, static_cast<int>(max_length)); | 734 return std::min(whole_path_limit, static_cast<int>(max_length)); |
| 868 } | 735 } |
| 869 | 736 |
| 870 } // namespace file_util | 737 } // namespace file_util |
| OLD | NEW |