OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <shellapi.h> | 8 #include <shellapi.h> |
9 #include <shlobj.h> | 9 #include <shlobj.h> |
10 #include <time.h> | 10 #include <time.h> |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 return (err == 0 || err == ERROR_FILE_NOT_FOUND); | 94 return (err == 0 || err == ERROR_FILE_NOT_FOUND); |
95 } | 95 } |
96 | 96 |
97 bool Move(const FilePath& from_path, const FilePath& to_path) { | 97 bool Move(const FilePath& from_path, const FilePath& to_path) { |
98 // NOTE: I suspect we could support longer paths, but that would involve | 98 // NOTE: I suspect we could support longer paths, but that would involve |
99 // analyzing all our usage of files. | 99 // analyzing all our usage of files. |
100 if (from_path.value().length() >= MAX_PATH || | 100 if (from_path.value().length() >= MAX_PATH || |
101 to_path.value().length() >= MAX_PATH) { | 101 to_path.value().length() >= MAX_PATH) { |
102 return false; | 102 return false; |
103 } | 103 } |
104 return (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), | 104 if (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), |
105 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0); | 105 MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0) |
| 106 return true; |
| 107 if (DirectoryExists(from_path)) { |
| 108 // MoveFileEx fails if moving directory across volumes. We will simulate |
| 109 // the move by using Copy and Delete. Ideally we could check whether |
| 110 // from_path and to_path are indeed in different volumes. |
| 111 return CopyAndDeleteDirectory(from_path, to_path); |
| 112 } |
| 113 return false; |
106 } | 114 } |
107 | 115 |
108 bool CopyFile(const FilePath& from_path, const FilePath& to_path) { | 116 bool CopyFile(const FilePath& from_path, const FilePath& to_path) { |
109 // NOTE: I suspect we could support longer paths, but that would involve | 117 // NOTE: I suspect we could support longer paths, but that would involve |
110 // analyzing all our usage of files. | 118 // analyzing all our usage of files. |
111 if (from_path.value().length() >= MAX_PATH || | 119 if (from_path.value().length() >= MAX_PATH || |
112 to_path.value().length() >= MAX_PATH) { | 120 to_path.value().length() >= MAX_PATH) { |
113 return false; | 121 return false; |
114 } | 122 } |
115 return (::CopyFile(from_path.value().c_str(), to_path.value().c_str(), | 123 return (::CopyFile(from_path.value().c_str(), to_path.value().c_str(), |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) | 168 if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) |
161 CreateDirectory(to_path); | 169 CreateDirectory(to_path); |
162 else | 170 else |
163 ShellCopy(from_path, to_path, false); | 171 ShellCopy(from_path, to_path, false); |
164 } | 172 } |
165 | 173 |
166 FilePath directory = from_path.Append(L"*.*"); | 174 FilePath directory = from_path.Append(L"*.*"); |
167 return ShellCopy(directory, to_path, false); | 175 return ShellCopy(directory, to_path, false); |
168 } | 176 } |
169 | 177 |
| 178 bool CopyAndDeleteDirectory(const FilePath& from_path, |
| 179 const FilePath& to_path) { |
| 180 if (CopyDirectory(from_path, to_path, true)) { |
| 181 if (Delete(from_path, true)) { |
| 182 return true; |
| 183 } |
| 184 // Like Move, this function is not transactional, so we just |
| 185 // leave the copied bits behind if deleting from_path fails. |
| 186 // If to_path exists previously then we have already overwritten |
| 187 // it by now, we don't get better off by deleting the new bits. |
| 188 } |
| 189 return false; |
| 190 } |
| 191 |
| 192 |
170 bool PathExists(const FilePath& path) { | 193 bool PathExists(const FilePath& path) { |
171 return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES); | 194 return (GetFileAttributes(path.value().c_str()) != INVALID_FILE_ATTRIBUTES); |
172 } | 195 } |
173 | 196 |
174 bool PathIsWritable(const FilePath& path) { | 197 bool PathIsWritable(const FilePath& path) { |
175 HANDLE dir = | 198 HANDLE dir = |
176 CreateFile(path.value().c_str(), FILE_ADD_FILE, | 199 CreateFile(path.value().c_str(), FILE_ADD_FILE, |
177 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 200 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
178 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | 201 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
179 | 202 |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 void PathComponents(const std::wstring& path, | 794 void PathComponents(const std::wstring& path, |
772 std::vector<std::wstring>* components) { | 795 std::vector<std::wstring>* components) { |
773 PathComponents(FilePath(path), components); | 796 PathComponents(FilePath(path), components); |
774 } | 797 } |
775 void ReplaceExtension(std::wstring* file_name, const std::wstring& extension) { | 798 void ReplaceExtension(std::wstring* file_name, const std::wstring& extension) { |
776 FilePath path(*file_name); | 799 FilePath path(*file_name); |
777 ReplaceExtension(&path, extension); | 800 ReplaceExtension(&path, extension); |
778 file_name->assign(path.value()); | 801 file_name->assign(path.value()); |
779 } | 802 } |
780 } // namespace file_util | 803 } // namespace file_util |
OLD | NEW |