Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: base/file_util_win.cc

Issue 43069: file_util::Move fails on Windows if moving a directory... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_util_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « base/file_util_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698