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 |