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

Side by Side Diff: base/files/file_util_win.cc

Issue 603683005: base::CopyFile can copy *from* Android's content scheme. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: base::internal::CopyFileUnsafe -> base::CopyFile Created 6 years, 1 month 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
« no previous file with comments | « base/files/file_util_unittest.cc ('k') | no next file » | 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/files/file_util.h" 5 #include "base/files/file_util.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <io.h> 8 #include <io.h>
9 #include <psapi.h> 9 #include <psapi.h>
10 #include <shellapi.h> 10 #include <shellapi.h>
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 } 203 }
204 } 204 }
205 205
206 if (from_is_dir) { 206 if (from_is_dir) {
207 if (!DirectoryExists(target_path) && 207 if (!DirectoryExists(target_path) &&
208 !::CreateDirectory(target_path.value().c_str(), NULL)) { 208 !::CreateDirectory(target_path.value().c_str(), NULL)) {
209 DLOG(ERROR) << "CopyDirectory() couldn't create directory: " 209 DLOG(ERROR) << "CopyDirectory() couldn't create directory: "
210 << target_path.value().c_str(); 210 << target_path.value().c_str();
211 success = false; 211 success = false;
212 } 212 }
213 } else if (!internal::CopyFileUnsafe(current, target_path)) { 213 } else if (!CopyFile(current, target_path)) {
214 DLOG(ERROR) << "CopyDirectory() couldn't create file: " 214 DLOG(ERROR) << "CopyDirectory() couldn't create file: "
215 << target_path.value().c_str(); 215 << target_path.value().c_str();
216 success = false; 216 success = false;
217 } 217 }
218 218
219 current = traversal.Next(); 219 current = traversal.Next();
220 if (!current.empty()) 220 if (!current.empty())
221 from_is_dir = traversal.GetInfo().IsDirectory(); 221 from_is_dir = traversal.GetInfo().IsDirectory();
222 } 222 }
223 223
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 } 715 }
716 716
717 // Length of |path| with path separator appended. 717 // Length of |path| with path separator appended.
718 size_t prefix = path.StripTrailingSeparators().value().size() + 1; 718 size_t prefix = path.StripTrailingSeparators().value().size() + 1;
719 // The whole path string must be shorter than MAX_PATH. That is, it must be 719 // The whole path string must be shorter than MAX_PATH. That is, it must be
720 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). 720 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1).
721 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); 721 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix));
722 return std::min(whole_path_limit, static_cast<int>(max_length)); 722 return std::min(whole_path_limit, static_cast<int>(max_length));
723 } 723 }
724 724
725 bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
726 ThreadRestrictions::AssertIOAllowed();
727 if (from_path.ReferencesParent() || to_path.ReferencesParent())
728 return false;
729
730 // NOTE: I suspect we could support longer paths, but that would involve
731 // analyzing all our usage of files.
732 if (from_path.value().length() >= MAX_PATH ||
733 to_path.value().length() >= MAX_PATH) {
734 return false;
735 }
736
737 // Unlike the posix implementation that copies the file manually and discards
738 // the ACL bits, CopyFile() copies the complete SECURITY_DESCRIPTOR and access
739 // bits, which is usually not what we want. We can't do much about the
740 // SECURITY_DESCRIPTOR but at least remove the read only bit.
741 const wchar_t* dest = to_path.value().c_str();
742 if (!::CopyFile(from_path.value().c_str(), dest, false)) {
743 // Copy failed.
744 return false;
745 }
746 DWORD attrs = GetFileAttributes(dest);
747 if (attrs == INVALID_FILE_ATTRIBUTES) {
748 return false;
749 }
750 if (attrs & FILE_ATTRIBUTE_READONLY) {
751 SetFileAttributes(dest, attrs & ~FILE_ATTRIBUTE_READONLY);
752 }
753 return true;
754 }
755
725 // ----------------------------------------------------------------------------- 756 // -----------------------------------------------------------------------------
726 757
727 namespace internal { 758 namespace internal {
728 759
729 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) { 760 bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {
730 ThreadRestrictions::AssertIOAllowed(); 761 ThreadRestrictions::AssertIOAllowed();
731 762
732 // NOTE: I suspect we could support longer paths, but that would involve 763 // NOTE: I suspect we could support longer paths, but that would involve
733 // analyzing all our usage of files. 764 // analyzing all our usage of files.
734 if (from_path.value().length() >= MAX_PATH || 765 if (from_path.value().length() >= MAX_PATH ||
(...skipping 18 matching lines...) Expand all
753 784
754 if (!ret) { 785 if (!ret) {
755 // Leave a clue about what went wrong so that it can be (at least) picked 786 // Leave a clue about what went wrong so that it can be (at least) picked
756 // up by a PLOG entry. 787 // up by a PLOG entry.
757 ::SetLastError(last_error); 788 ::SetLastError(last_error);
758 } 789 }
759 790
760 return ret; 791 return ret;
761 } 792 }
762 793
763 bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) {
764 ThreadRestrictions::AssertIOAllowed();
765
766 // NOTE: I suspect we could support longer paths, but that would involve
767 // analyzing all our usage of files.
768 if (from_path.value().length() >= MAX_PATH ||
769 to_path.value().length() >= MAX_PATH) {
770 return false;
771 }
772
773 // Unlike the posix implementation that copies the file manually and discards
774 // the ACL bits, CopyFile() copies the complete SECURITY_DESCRIPTOR and access
775 // bits, which is usually not what we want. We can't do much about the
776 // SECURITY_DESCRIPTOR but at least remove the read only bit.
777 const wchar_t* dest = to_path.value().c_str();
778 if (!::CopyFile(from_path.value().c_str(), dest, false)) {
779 // Copy failed.
780 return false;
781 }
782 DWORD attrs = GetFileAttributes(dest);
783 if (attrs == INVALID_FILE_ATTRIBUTES) {
784 return false;
785 }
786 if (attrs & FILE_ATTRIBUTE_READONLY) {
787 SetFileAttributes(dest, attrs & ~FILE_ATTRIBUTE_READONLY);
788 }
789 return true;
790 }
791
792 bool CopyAndDeleteDirectory(const FilePath& from_path, 794 bool CopyAndDeleteDirectory(const FilePath& from_path,
793 const FilePath& to_path) { 795 const FilePath& to_path) {
794 ThreadRestrictions::AssertIOAllowed(); 796 ThreadRestrictions::AssertIOAllowed();
795 if (CopyDirectory(from_path, to_path, true)) { 797 if (CopyDirectory(from_path, to_path, true)) {
796 if (DeleteFile(from_path, true)) 798 if (DeleteFile(from_path, true))
797 return true; 799 return true;
798 800
799 // Like Move, this function is not transactional, so we just 801 // Like Move, this function is not transactional, so we just
800 // leave the copied bits behind if deleting from_path fails. 802 // leave the copied bits behind if deleting from_path fails.
801 // If to_path exists previously then we have already overwritten 803 // If to_path exists previously then we have already overwritten
802 // it by now, we don't get better off by deleting the new bits. 804 // it by now, we don't get better off by deleting the new bits.
803 } 805 }
804 return false; 806 return false;
805 } 807 }
806 808
807 } // namespace internal 809 } // namespace internal
808 } // namespace base 810 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_util_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698