| 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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 } | 169 } |
| 170 | 170 |
| 171 bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, | 171 bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, |
| 172 bool recursive) { | 172 bool recursive) { |
| 173 ThreadRestrictions::AssertIOAllowed(); | 173 ThreadRestrictions::AssertIOAllowed(); |
| 174 | 174 |
| 175 if (recursive) | 175 if (recursive) |
| 176 return ShellCopy(from_path, to_path, true); | 176 return ShellCopy(from_path, to_path, true); |
| 177 | 177 |
| 178 // The following code assumes that from path is a directory. | 178 // The following code assumes that from path is a directory. |
| 179 DCHECK(file_util::DirectoryExists(from_path)); | 179 DCHECK(DirectoryExists(from_path)); |
| 180 | 180 |
| 181 // Instead of creating a new directory, we copy the old one to include the | 181 // Instead of creating a new directory, we copy the old one to include the |
| 182 // security information of the folder as part of the copy. | 182 // security information of the folder as part of the copy. |
| 183 if (!PathExists(to_path)) { | 183 if (!PathExists(to_path)) { |
| 184 // Except that Vista fails to do that, and instead do a recursive copy if | 184 // Except that Vista fails to do that, and instead do a recursive copy if |
| 185 // the target directory doesn't exist. | 185 // the target directory doesn't exist. |
| 186 if (base::win::GetVersion() >= base::win::VERSION_VISTA) | 186 if (base::win::GetVersion() >= base::win::VERSION_VISTA) |
| 187 file_util::CreateDirectory(to_path); | 187 file_util::CreateDirectory(to_path); |
| 188 else | 188 else |
| 189 ShellCopy(from_path, to_path, false); | 189 ShellCopy(from_path, to_path, false); |
| 190 } | 190 } |
| 191 | 191 |
| 192 FilePath directory = from_path.Append(L"*.*"); | 192 FilePath directory = from_path.Append(L"*.*"); |
| 193 return ShellCopy(directory, to_path, false); | 193 return ShellCopy(directory, to_path, false); |
| 194 } | 194 } |
| 195 | 195 |
| 196 bool PathExists(const FilePath& path) { | 196 bool PathExists(const FilePath& path) { |
| 197 ThreadRestrictions::AssertIOAllowed(); | 197 ThreadRestrictions::AssertIOAllowed(); |
| 198 return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES); | 198 return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES); |
| 199 } | 199 } |
| 200 | 200 |
| 201 } // namespace base | |
| 202 | |
| 203 // ----------------------------------------------------------------------------- | |
| 204 | |
| 205 namespace file_util { | |
| 206 | |
| 207 using base::FilePath; | |
| 208 using base::kFileShareAll; | |
| 209 | |
| 210 bool PathIsWritable(const FilePath& path) { | 201 bool PathIsWritable(const FilePath& path) { |
| 211 base::ThreadRestrictions::AssertIOAllowed(); | 202 ThreadRestrictions::AssertIOAllowed(); |
| 212 HANDLE dir = | 203 HANDLE dir = |
| 213 CreateFile(path.value().c_str(), FILE_ADD_FILE, kFileShareAll, | 204 CreateFile(path.value().c_str(), FILE_ADD_FILE, kFileShareAll, |
| 214 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | 205 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 215 | 206 |
| 216 if (dir == INVALID_HANDLE_VALUE) | 207 if (dir == INVALID_HANDLE_VALUE) |
| 217 return false; | 208 return false; |
| 218 | 209 |
| 219 CloseHandle(dir); | 210 CloseHandle(dir); |
| 220 return true; | 211 return true; |
| 221 } | 212 } |
| 222 | 213 |
| 223 bool DirectoryExists(const FilePath& path) { | 214 bool DirectoryExists(const FilePath& path) { |
| 224 base::ThreadRestrictions::AssertIOAllowed(); | 215 ThreadRestrictions::AssertIOAllowed(); |
| 225 DWORD fileattr = GetFileAttributes(path.value().c_str()); | 216 DWORD fileattr = GetFileAttributes(path.value().c_str()); |
| 226 if (fileattr != INVALID_FILE_ATTRIBUTES) | 217 if (fileattr != INVALID_FILE_ATTRIBUTES) |
| 227 return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0; | 218 return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0; |
| 228 return false; | 219 return false; |
| 229 } | 220 } |
| 230 | 221 |
| 222 } // namespace base |
| 223 |
| 224 // ----------------------------------------------------------------------------- |
| 225 |
| 226 namespace file_util { |
| 227 |
| 228 using base::DirectoryExists; |
| 229 using base::FilePath; |
| 230 using base::kFileShareAll; |
| 231 |
| 231 bool GetTempDir(FilePath* path) { | 232 bool GetTempDir(FilePath* path) { |
| 232 base::ThreadRestrictions::AssertIOAllowed(); | 233 base::ThreadRestrictions::AssertIOAllowed(); |
| 233 | 234 |
| 234 wchar_t temp_path[MAX_PATH + 1]; | 235 wchar_t temp_path[MAX_PATH + 1]; |
| 235 DWORD path_len = ::GetTempPath(MAX_PATH, temp_path); | 236 DWORD path_len = ::GetTempPath(MAX_PATH, temp_path); |
| 236 if (path_len >= MAX_PATH || path_len <= 0) | 237 if (path_len >= MAX_PATH || path_len <= 0) |
| 237 return false; | 238 return false; |
| 238 // TODO(evanm): the old behavior of this function was to always strip the | 239 // TODO(evanm): the old behavior of this function was to always strip the |
| 239 // trailing slash. We duplicate this here, but it shouldn't be necessary | 240 // trailing slash. We duplicate this here, but it shouldn't be necessary |
| 240 // when everyone is using the appropriate FilePath APIs. | 241 // when everyone is using the appropriate FilePath APIs. |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 } | 704 } |
| 704 if (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), | 705 if (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), |
| 705 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0) | 706 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0) |
| 706 return true; | 707 return true; |
| 707 | 708 |
| 708 // Keep the last error value from MoveFileEx around in case the below | 709 // Keep the last error value from MoveFileEx around in case the below |
| 709 // fails. | 710 // fails. |
| 710 bool ret = false; | 711 bool ret = false; |
| 711 DWORD last_error = ::GetLastError(); | 712 DWORD last_error = ::GetLastError(); |
| 712 | 713 |
| 713 if (file_util::DirectoryExists(from_path)) { | 714 if (DirectoryExists(from_path)) { |
| 714 // MoveFileEx fails if moving directory across volumes. We will simulate | 715 // MoveFileEx fails if moving directory across volumes. We will simulate |
| 715 // the move by using Copy and Delete. Ideally we could check whether | 716 // the move by using Copy and Delete. Ideally we could check whether |
| 716 // from_path and to_path are indeed in different volumes. | 717 // from_path and to_path are indeed in different volumes. |
| 717 ret = internal::CopyAndDeleteDirectory(from_path, to_path); | 718 ret = internal::CopyAndDeleteDirectory(from_path, to_path); |
| 718 } | 719 } |
| 719 | 720 |
| 720 if (!ret) { | 721 if (!ret) { |
| 721 // Leave a clue about what went wrong so that it can be (at least) picked | 722 // Leave a clue about what went wrong so that it can be (at least) picked |
| 722 // up by a PLOG entry. | 723 // up by a PLOG entry. |
| 723 ::SetLastError(last_error); | 724 ::SetLastError(last_error); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 749 // Like Move, this function is not transactional, so we just | 750 // Like Move, this function is not transactional, so we just |
| 750 // leave the copied bits behind if deleting from_path fails. | 751 // leave the copied bits behind if deleting from_path fails. |
| 751 // If to_path exists previously then we have already overwritten | 752 // If to_path exists previously then we have already overwritten |
| 752 // it by now, we don't get better off by deleting the new bits. | 753 // it by now, we don't get better off by deleting the new bits. |
| 753 } | 754 } |
| 754 return false; | 755 return false; |
| 755 } | 756 } |
| 756 | 757 |
| 757 } // namespace internal | 758 } // namespace internal |
| 758 } // namespace base | 759 } // namespace base |
| OLD | NEW |