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 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 | 721 |
722 bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) { | 722 bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) { |
723 ThreadRestrictions::AssertIOAllowed(); | 723 ThreadRestrictions::AssertIOAllowed(); |
724 | 724 |
725 // NOTE: I suspect we could support longer paths, but that would involve | 725 // NOTE: I suspect we could support longer paths, but that would involve |
726 // analyzing all our usage of files. | 726 // analyzing all our usage of files. |
727 if (from_path.value().length() >= MAX_PATH || | 727 if (from_path.value().length() >= MAX_PATH || |
728 to_path.value().length() >= MAX_PATH) { | 728 to_path.value().length() >= MAX_PATH) { |
729 return false; | 729 return false; |
730 } | 730 } |
731 return (::CopyFile(from_path.value().c_str(), to_path.value().c_str(), | 731 |
732 false) != 0); | 732 // Unlike the posix implementation that copies the file manually and discards |
| 733 // the ACL bits, CopyFile() copies the complete SECURITY_DESCRIPTOR and access |
| 734 // bits, which is usually not what we want. We can't do much about the |
| 735 // SECURITY_DESCRIPTOR but at least remove the read only bit. |
| 736 const wchar_t* dest = to_path.value().c_str(); |
| 737 if (!::CopyFile(from_path.value().c_str(), dest, false)) { |
| 738 // Copy failed. |
| 739 return false; |
| 740 } |
| 741 DWORD attrs = GetFileAttributes(dest); |
| 742 if (attrs == INVALID_FILE_ATTRIBUTES) { |
| 743 return false; |
| 744 } |
| 745 if (attrs & FILE_ATTRIBUTE_READONLY) { |
| 746 SetFileAttributes(dest, attrs & ~FILE_ATTRIBUTE_READONLY); |
| 747 } |
| 748 return true; |
733 } | 749 } |
734 | 750 |
735 bool CopyAndDeleteDirectory(const FilePath& from_path, | 751 bool CopyAndDeleteDirectory(const FilePath& from_path, |
736 const FilePath& to_path) { | 752 const FilePath& to_path) { |
737 ThreadRestrictions::AssertIOAllowed(); | 753 ThreadRestrictions::AssertIOAllowed(); |
738 if (CopyDirectory(from_path, to_path, true)) { | 754 if (CopyDirectory(from_path, to_path, true)) { |
739 if (DeleteFile(from_path, true)) | 755 if (DeleteFile(from_path, true)) |
740 return true; | 756 return true; |
741 | 757 |
742 // Like Move, this function is not transactional, so we just | 758 // Like Move, this function is not transactional, so we just |
743 // leave the copied bits behind if deleting from_path fails. | 759 // leave the copied bits behind if deleting from_path fails. |
744 // If to_path exists previously then we have already overwritten | 760 // If to_path exists previously then we have already overwritten |
745 // it by now, we don't get better off by deleting the new bits. | 761 // it by now, we don't get better off by deleting the new bits. |
746 } | 762 } |
747 return false; | 763 return false; |
748 } | 764 } |
749 | 765 |
750 } // namespace internal | 766 } // namespace internal |
751 } // namespace base | 767 } // namespace base |
OLD | NEW |