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

Unified Diff: base/file_util_win.cc

Issue 18332014: Move Copy* into the base namespace. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: windows Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/file_util_unittest.cc ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/file_util_win.cc
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 2a56ea9468485f60ffc887b0e496d68467e03b78..928b66e525b16bd0f70426a0f625067a8a854ffc 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -34,6 +34,44 @@ namespace {
const DWORD kFileShareAll =
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+bool ShellCopy(const FilePath& from_path,
+ const FilePath& to_path,
+ bool recursive) {
+ // WinXP SHFileOperation doesn't like trailing separators.
+ FilePath stripped_from = from_path.StripTrailingSeparators();
+ FilePath stripped_to = to_path.StripTrailingSeparators();
+
+ ThreadRestrictions::AssertIOAllowed();
+
+ // NOTE: I suspect we could support longer paths, but that would involve
+ // analyzing all our usage of files.
+ if (stripped_from.value().length() >= MAX_PATH ||
+ stripped_to.value().length() >= MAX_PATH) {
+ return false;
+ }
+
+ // SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
+ // so we have to use wcscpy because wcscpy_s writes non-NULLs
+ // into the rest of the buffer.
+ wchar_t double_terminated_path_from[MAX_PATH + 1] = {0};
+ wchar_t double_terminated_path_to[MAX_PATH + 1] = {0};
+#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
+ wcscpy(double_terminated_path_from, stripped_from.value().c_str());
+#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
+ wcscpy(double_terminated_path_to, stripped_to.value().c_str());
+
+ SHFILEOPSTRUCT file_operation = {0};
+ file_operation.wFunc = FO_COPY;
+ file_operation.pFrom = double_terminated_path_from;
+ file_operation.pTo = double_terminated_path_to;
+ file_operation.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION |
+ FOF_NOCONFIRMMKDIR;
+ if (!recursive)
+ file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY;
+
+ return (SHFileOperation(&file_operation) == 0);
+}
+
} // namespace
FilePath MakeAbsoluteFilePath(const FilePath& input) {
@@ -109,40 +147,6 @@ bool DeleteAfterReboot(const FilePath& path) {
MOVEFILE_REPLACE_EXISTING) != FALSE;
}
-bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {
- ThreadRestrictions::AssertIOAllowed();
-
- // NOTE: I suspect we could support longer paths, but that would involve
- // analyzing all our usage of files.
- if (from_path.value().length() >= MAX_PATH ||
- to_path.value().length() >= MAX_PATH) {
- return false;
- }
- if (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(),
- MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0)
- return true;
-
- // Keep the last error value from MoveFileEx around in case the below
- // fails.
- bool ret = false;
- DWORD last_error = ::GetLastError();
-
- if (file_util::DirectoryExists(from_path)) {
- // MoveFileEx fails if moving directory across volumes. We will simulate
- // the move by using Copy and Delete. Ideally we could check whether
- // from_path and to_path are indeed in different volumes.
- ret = file_util::CopyAndDeleteDirectory(from_path, to_path);
- }
-
- if (!ret) {
- // Leave a clue about what went wrong so that it can be (at least) picked
- // up by a PLOG entry.
- ::SetLastError(last_error);
- }
-
- return ret;
-}
-
bool ReplaceFile(const FilePath& from_path,
const FilePath& to_path,
PlatformFileError* error) {
@@ -164,82 +168,23 @@ bool ReplaceFile(const FilePath& from_path,
return false;
}
-} // namespace base
-
-// -----------------------------------------------------------------------------
-
-namespace file_util {
-
-using base::FilePath;
-using base::kFileShareAll;
-
-bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) {
- base::ThreadRestrictions::AssertIOAllowed();
-
- // NOTE: I suspect we could support longer paths, but that would involve
- // analyzing all our usage of files.
- if (from_path.value().length() >= MAX_PATH ||
- to_path.value().length() >= MAX_PATH) {
- return false;
- }
- return (::CopyFile(from_path.value().c_str(), to_path.value().c_str(),
- false) != 0);
-}
-
-bool ShellCopy(const FilePath& from_path, const FilePath& to_path,
- bool recursive) {
- // WinXP SHFileOperation doesn't like trailing separators.
- FilePath stripped_from = from_path.StripTrailingSeparators();
- FilePath stripped_to = to_path.StripTrailingSeparators();
-
- base::ThreadRestrictions::AssertIOAllowed();
-
- // NOTE: I suspect we could support longer paths, but that would involve
- // analyzing all our usage of files.
- if (stripped_from.value().length() >= MAX_PATH ||
- stripped_to.value().length() >= MAX_PATH) {
- return false;
- }
-
- // SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
- // so we have to use wcscpy because wcscpy_s writes non-NULLs
- // into the rest of the buffer.
- wchar_t double_terminated_path_from[MAX_PATH + 1] = {0};
- wchar_t double_terminated_path_to[MAX_PATH + 1] = {0};
-#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
- wcscpy(double_terminated_path_from, stripped_from.value().c_str());
-#pragma warning(suppress:4996) // don't complain about wcscpy deprecation
- wcscpy(double_terminated_path_to, stripped_to.value().c_str());
-
- SHFILEOPSTRUCT file_operation = {0};
- file_operation.wFunc = FO_COPY;
- file_operation.pFrom = double_terminated_path_from;
- file_operation.pTo = double_terminated_path_to;
- file_operation.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION |
- FOF_NOCONFIRMMKDIR;
- if (!recursive)
- file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY;
-
- return (SHFileOperation(&file_operation) == 0);
-}
-
bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
bool recursive) {
- base::ThreadRestrictions::AssertIOAllowed();
+ ThreadRestrictions::AssertIOAllowed();
if (recursive)
return ShellCopy(from_path, to_path, true);
// The following code assumes that from path is a directory.
- DCHECK(DirectoryExists(from_path));
+ DCHECK(file_util::DirectoryExists(from_path));
// Instead of creating a new directory, we copy the old one to include the
// security information of the folder as part of the copy.
- if (!PathExists(to_path)) {
+ if (!file_util::PathExists(to_path)) {
// Except that Vista fails to do that, and instead do a recursive copy if
// the target directory doesn't exist.
if (base::win::GetVersion() >= base::win::VERSION_VISTA)
- CreateDirectory(to_path);
+ file_util::CreateDirectory(to_path);
else
ShellCopy(from_path, to_path, false);
}
@@ -248,21 +193,14 @@ bool CopyDirectory(const FilePath& from_path, const FilePath& to_path,
return ShellCopy(directory, to_path, false);
}
-bool CopyAndDeleteDirectory(const FilePath& from_path,
- const FilePath& to_path) {
- base::ThreadRestrictions::AssertIOAllowed();
- if (CopyDirectory(from_path, to_path, true)) {
- if (Delete(from_path, true)) {
- return true;
- }
- // Like Move, this function is not transactional, so we just
- // leave the copied bits behind if deleting from_path fails.
- // If to_path exists previously then we have already overwritten
- // it by now, we don't get better off by deleting the new bits.
- }
- return false;
-}
+} // namespace base
+
+// -----------------------------------------------------------------------------
+
+namespace file_util {
+using base::FilePath;
+using base::kFileShareAll;
bool PathExists(const FilePath& path) {
base::ThreadRestrictions::AssertIOAllowed();
@@ -750,3 +688,71 @@ int GetMaximumPathComponentLength(const FilePath& path) {
}
} // namespace file_util
+
+namespace base {
+namespace internal {
+
+bool MoveUnsafe(const FilePath& from_path, const FilePath& to_path) {
+ ThreadRestrictions::AssertIOAllowed();
+
+ // NOTE: I suspect we could support longer paths, but that would involve
+ // analyzing all our usage of files.
+ if (from_path.value().length() >= MAX_PATH ||
+ to_path.value().length() >= MAX_PATH) {
+ return false;
+ }
+ if (MoveFileEx(from_path.value().c_str(), to_path.value().c_str(),
+ MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) != 0)
+ return true;
+
+ // Keep the last error value from MoveFileEx around in case the below
+ // fails.
+ bool ret = false;
+ DWORD last_error = ::GetLastError();
+
+ if (file_util::DirectoryExists(from_path)) {
+ // MoveFileEx fails if moving directory across volumes. We will simulate
+ // the move by using Copy and Delete. Ideally we could check whether
+ // from_path and to_path are indeed in different volumes.
+ ret = internal::CopyAndDeleteDirectory(from_path, to_path);
+ }
+
+ if (!ret) {
+ // Leave a clue about what went wrong so that it can be (at least) picked
+ // up by a PLOG entry.
+ ::SetLastError(last_error);
+ }
+
+ return ret;
+}
+
+bool CopyFileUnsafe(const FilePath& from_path, const FilePath& to_path) {
+ ThreadRestrictions::AssertIOAllowed();
+
+ // NOTE: I suspect we could support longer paths, but that would involve
+ // analyzing all our usage of files.
+ if (from_path.value().length() >= MAX_PATH ||
+ to_path.value().length() >= MAX_PATH) {
+ return false;
+ }
+ return (::CopyFile(from_path.value().c_str(), to_path.value().c_str(),
+ false) != 0);
+}
+
+bool CopyAndDeleteDirectory(const FilePath& from_path,
+ const FilePath& to_path) {
+ ThreadRestrictions::AssertIOAllowed();
+ if (CopyDirectory(from_path, to_path, true)) {
+ if (Delete(from_path, true))
+ return true;
+
+ // Like Move, this function is not transactional, so we just
+ // leave the copied bits behind if deleting from_path fails.
+ // If to_path exists previously then we have already overwritten
+ // it by now, we don't get better off by deleting the new bits.
+ }
+ return false;
+}
+
+} // namespace internal
+} // namespace base
« no previous file with comments | « base/file_util_unittest.cc ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698