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 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 return true; | 615 return true; |
616 } | 616 } |
617 | 617 |
618 // Sets the current working directory for the process. | 618 // Sets the current working directory for the process. |
619 bool SetCurrentDirectory(const FilePath& directory) { | 619 bool SetCurrentDirectory(const FilePath& directory) { |
620 base::ThreadRestrictions::AssertIOAllowed(); | 620 base::ThreadRestrictions::AssertIOAllowed(); |
621 BOOL ret = ::SetCurrentDirectory(directory.value().c_str()); | 621 BOOL ret = ::SetCurrentDirectory(directory.value().c_str()); |
622 return ret != 0; | 622 return ret != 0; |
623 } | 623 } |
624 | 624 |
625 /////////////////////////////////////////////// | |
626 // FileEnumerator | |
627 | |
628 FileEnumerator::FileEnumerator(const FilePath& root_path, | |
629 bool recursive, | |
630 int file_type) | |
631 : recursive_(recursive), | |
632 file_type_(file_type), | |
633 has_find_data_(false), | |
634 find_handle_(INVALID_HANDLE_VALUE) { | |
635 // INCLUDE_DOT_DOT must not be specified if recursive. | |
636 DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); | |
637 memset(&find_data_, 0, sizeof(find_data_)); | |
638 pending_paths_.push(root_path); | |
639 } | |
640 | |
641 FileEnumerator::FileEnumerator(const FilePath& root_path, | |
642 bool recursive, | |
643 int file_type, | |
644 const FilePath::StringType& pattern) | |
645 : recursive_(recursive), | |
646 file_type_(file_type), | |
647 has_find_data_(false), | |
648 pattern_(pattern), | |
649 find_handle_(INVALID_HANDLE_VALUE) { | |
650 // INCLUDE_DOT_DOT must not be specified if recursive. | |
651 DCHECK(!(recursive && (INCLUDE_DOT_DOT & file_type_))); | |
652 memset(&find_data_, 0, sizeof(find_data_)); | |
653 pending_paths_.push(root_path); | |
654 } | |
655 | |
656 FileEnumerator::~FileEnumerator() { | |
657 if (find_handle_ != INVALID_HANDLE_VALUE) | |
658 FindClose(find_handle_); | |
659 } | |
660 | |
661 void FileEnumerator::GetFindInfo(FindInfo* info) { | |
662 DCHECK(info); | |
663 | |
664 if (!has_find_data_) | |
665 return; | |
666 | |
667 memcpy(info, &find_data_, sizeof(*info)); | |
668 } | |
669 | |
670 // static | |
671 bool FileEnumerator::IsDirectory(const FindInfo& info) { | |
672 return (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | |
673 } | |
674 | |
675 // static | |
676 FilePath FileEnumerator::GetFilename(const FindInfo& find_info) { | |
677 return FilePath(find_info.cFileName); | |
678 } | |
679 | |
680 // static | |
681 int64 FileEnumerator::GetFilesize(const FindInfo& find_info) { | |
682 ULARGE_INTEGER size; | |
683 size.HighPart = find_info.nFileSizeHigh; | |
684 size.LowPart = find_info.nFileSizeLow; | |
685 DCHECK_LE(size.QuadPart, std::numeric_limits<int64>::max()); | |
686 return static_cast<int64>(size.QuadPart); | |
687 } | |
688 | |
689 // static | |
690 base::Time FileEnumerator::GetLastModifiedTime(const FindInfo& find_info) { | |
691 return base::Time::FromFileTime(find_info.ftLastWriteTime); | |
692 } | |
693 | |
694 FilePath FileEnumerator::Next() { | |
695 base::ThreadRestrictions::AssertIOAllowed(); | |
696 | |
697 while (has_find_data_ || !pending_paths_.empty()) { | |
698 if (!has_find_data_) { | |
699 // The last find FindFirstFile operation is done, prepare a new one. | |
700 root_path_ = pending_paths_.top(); | |
701 pending_paths_.pop(); | |
702 | |
703 // Start a new find operation. | |
704 FilePath src = root_path_; | |
705 | |
706 if (pattern_.empty()) | |
707 src = src.Append(L"*"); // No pattern = match everything. | |
708 else | |
709 src = src.Append(pattern_); | |
710 | |
711 find_handle_ = FindFirstFile(src.value().c_str(), &find_data_); | |
712 has_find_data_ = true; | |
713 } else { | |
714 // Search for the next file/directory. | |
715 if (!FindNextFile(find_handle_, &find_data_)) { | |
716 FindClose(find_handle_); | |
717 find_handle_ = INVALID_HANDLE_VALUE; | |
718 } | |
719 } | |
720 | |
721 if (INVALID_HANDLE_VALUE == find_handle_) { | |
722 has_find_data_ = false; | |
723 | |
724 // This is reached when we have finished a directory and are advancing to | |
725 // the next one in the queue. We applied the pattern (if any) to the files | |
726 // in the root search directory, but for those directories which were | |
727 // matched, we want to enumerate all files inside them. This will happen | |
728 // when the handle is empty. | |
729 pattern_ = FilePath::StringType(); | |
730 | |
731 continue; | |
732 } | |
733 | |
734 FilePath cur_file(find_data_.cFileName); | |
735 if (ShouldSkip(cur_file)) | |
736 continue; | |
737 | |
738 // Construct the absolute filename. | |
739 cur_file = root_path_.Append(find_data_.cFileName); | |
740 | |
741 if (find_data_.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { | |
742 if (recursive_) { | |
743 // If |cur_file| is a directory, and we are doing recursive searching, | |
744 // add it to pending_paths_ so we scan it after we finish scanning this | |
745 // directory. | |
746 pending_paths_.push(cur_file); | |
747 } | |
748 if (file_type_ & FileEnumerator::DIRECTORIES) | |
749 return cur_file; | |
750 } else if (file_type_ & FileEnumerator::FILES) { | |
751 return cur_file; | |
752 } | |
753 } | |
754 | |
755 return FilePath(); | |
756 } | |
757 | |
758 bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, | 625 bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, |
759 const base::Time& cutoff_time) { | 626 const base::Time& cutoff_time) { |
760 base::ThreadRestrictions::AssertIOAllowed(); | 627 base::ThreadRestrictions::AssertIOAllowed(); |
761 FILETIME file_time = cutoff_time.ToFileTime(); | 628 FILETIME file_time = cutoff_time.ToFileTime(); |
762 long result = CompareFileTime(&find_info.ftLastWriteTime, // NOLINT | 629 long result = CompareFileTime(&find_info.ftLastWriteTime, // NOLINT |
763 &file_time); | 630 &file_time); |
764 return result == 1 || result == 0; | 631 return result == 1 || result == 0; |
765 } | 632 } |
766 | 633 |
767 bool NormalizeFilePath(const FilePath& path, FilePath* real_path) { | 634 bool NormalizeFilePath(const FilePath& path, FilePath* real_path) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 | 760 |
894 // Length of |path| with path separator appended. | 761 // Length of |path| with path separator appended. |
895 size_t prefix = path.StripTrailingSeparators().value().size() + 1; | 762 size_t prefix = path.StripTrailingSeparators().value().size() + 1; |
896 // The whole path string must be shorter than MAX_PATH. That is, it must be | 763 // The whole path string must be shorter than MAX_PATH. That is, it must be |
897 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). | 764 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). |
898 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); | 765 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); |
899 return std::min(whole_path_limit, static_cast<int>(max_length)); | 766 return std::min(whole_path_limit, static_cast<int>(max_length)); |
900 } | 767 } |
901 | 768 |
902 } // namespace file_util | 769 } // namespace file_util |
OLD | NEW |