Chromium Code Reviews| 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/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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 } | 127 } |
| 128 | 128 |
| 129 bool ReplaceFile(const FilePath& from_path, | 129 bool ReplaceFile(const FilePath& from_path, |
| 130 const FilePath& to_path, | 130 const FilePath& to_path, |
| 131 File::Error* error) { | 131 File::Error* error) { |
| 132 ThreadRestrictions::AssertIOAllowed(); | 132 ThreadRestrictions::AssertIOAllowed(); |
| 133 // Try a simple move first. It will only succeed when |to_path| doesn't | 133 // Try a simple move first. It will only succeed when |to_path| doesn't |
| 134 // already exist. | 134 // already exist. |
| 135 if (::MoveFile(from_path.value().c_str(), to_path.value().c_str())) | 135 if (::MoveFile(from_path.value().c_str(), to_path.value().c_str())) |
| 136 return true; | 136 return true; |
| 137 File::Error move_error = File::OSErrorToFileError(GetLastError()); | |
|
dcheng
2017/02/07 23:24:50
DWORD error_code = ::GetLastError();
| |
| 138 | |
| 137 // Try the full-blown replace if the move fails, as ReplaceFile will only | 139 // Try the full-blown replace if the move fails, as ReplaceFile will only |
| 138 // succeed when |to_path| does exist. When writing to a network share, we may | 140 // succeed when |to_path| does exist. When writing to a network share, we may |
| 139 // not be able to change the ACLs. Ignore ACL errors then | 141 // not be able to change the ACLs. Ignore ACL errors then |
| 140 // (REPLACEFILE_IGNORE_MERGE_ERRORS). | 142 // (REPLACEFILE_IGNORE_MERGE_ERRORS). |
| 141 if (::ReplaceFile(to_path.value().c_str(), from_path.value().c_str(), NULL, | 143 if (::ReplaceFile(to_path.value().c_str(), from_path.value().c_str(), NULL, |
| 142 REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL)) { | 144 REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL)) { |
| 143 return true; | 145 return true; |
| 144 } | 146 } |
| 145 if (error) | 147 // In the case of FILE_ERROR_NOT_FOUND from ReplaceFile, it is likely that |
| 146 *error = File::OSErrorToFileError(GetLastError()); | 148 // |to_path| does not exist. In this case, the more relevant error comes |
| 149 // from the call to MoveFile. | |
| 150 if (error) { | |
| 151 File::Error replace_error = File::OSErrorToFileError(GetLastError()); | |
| 152 *error = replace_error == File::FILE_ERROR_NOT_FOUND ? move_error | |
|
dcheng
2017/02/07 23:24:50
if ((replace_error = ::GetLastError()) != ERROR_FI
Charlie Harrison
2017/02/07 23:31:23
Going to push back on this, only because I think i
dcheng
2017/02/07 23:32:39
Makes sense, I'm OK with that.
| |
| 153 : replace_error; | |
| 154 } | |
| 147 return false; | 155 return false; |
| 148 } | 156 } |
| 149 | 157 |
| 150 bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, | 158 bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, |
| 151 bool recursive) { | 159 bool recursive) { |
| 152 // NOTE(maruel): Previous version of this function used to call | 160 // NOTE(maruel): Previous version of this function used to call |
| 153 // SHFileOperation(). This used to copy the file attributes and extended | 161 // SHFileOperation(). This used to copy the file attributes and extended |
| 154 // attributes, OLE structured storage, NTFS file system alternate data | 162 // attributes, OLE structured storage, NTFS file system alternate data |
| 155 // streams, SECURITY_DESCRIPTOR. In practice, this is not what we want, we | 163 // streams, SECURITY_DESCRIPTOR. In practice, this is not what we want, we |
| 156 // want the containing directory to propagate its SECURITY_DESCRIPTOR. | 164 // want the containing directory to propagate its SECURITY_DESCRIPTOR. |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 820 // Like Move, this function is not transactional, so we just | 828 // Like Move, this function is not transactional, so we just |
| 821 // leave the copied bits behind if deleting from_path fails. | 829 // leave the copied bits behind if deleting from_path fails. |
| 822 // If to_path exists previously then we have already overwritten | 830 // If to_path exists previously then we have already overwritten |
| 823 // it by now, we don't get better off by deleting the new bits. | 831 // it by now, we don't get better off by deleting the new bits. |
| 824 } | 832 } |
| 825 return false; | 833 return false; |
| 826 } | 834 } |
| 827 | 835 |
| 828 } // namespace internal | 836 } // namespace internal |
| 829 } // namespace base | 837 } // namespace base |
| OLD | NEW |