Index: base/file_util_win.cc |
diff --git a/base/file_util_win.cc b/base/file_util_win.cc |
index dd6282516e4f0a1888ac56da826476898bd9e758..9205b7e924fff18190cefb45e96ffcedf935d93f 100644 |
--- a/base/file_util_win.cc |
+++ b/base/file_util_win.cc |
@@ -15,6 +15,7 @@ |
#include <string> |
#include "base/files/file_path.h" |
+#include "base/files/file_enumerator.h" |
#include "base/logging.h" |
#include "base/metrics/histogram.h" |
#include "base/process/process_handle.h" |
@@ -34,6 +35,9 @@ namespace { |
const DWORD kFileShareAll = |
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; |
+// ShellCopy can copy directories, unlike CopyFileUnsafe. Beside that, they are |
+// mostly similar but both date backs to ~2008. |
+// This function is used exclusively for CopyDirectory(). |
bool ShellCopy(const FilePath& from_path, |
const FilePath& to_path, |
bool recursive) { |
@@ -65,11 +69,30 @@ bool ShellCopy(const FilePath& from_path, |
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; |
+ FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS; |
if (!recursive) |
file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY; |
- return (SHFileOperation(&file_operation) == 0); |
+ if (SHFileOperation(&file_operation) != 0) { |
grt (UTC plus 2)
2014/01/22 21:27:45
nit: omit braces for single-liners like this here
|
+ return false; |
+ } |
+ // Sadly at this point, all the read-only attributes have to be removed |
+ // manually, even if FOF_NOCOPYSECURITYATTRIBS is set. |
+ FileEnumerator f(to_path, true, FileEnumerator::FILES); |
grt (UTC plus 2)
2014/01/22 21:27:45
it looks like ShellCopy is expected to be called i
M-A Ruel
2014/01/23 01:00:50
You are right.
What about I rip out calls to Copy
|
+ while (true) { |
+ FilePath p = f.Next(); |
+ if (p.empty()) { |
+ break; |
+ } |
+ DWORD attrs = GetFileAttributes(p.value().c_str()); |
+ if (attrs == INVALID_FILE_ATTRIBUTES) { |
+ continue; |
+ } |
+ if (attrs & FILE_ATTRIBUTE_READONLY) { |
+ SetFileAttributes(p.value().c_str(), attrs & ~FILE_ATTRIBUTE_READONLY); |
+ } |
+ } |
+ return true; |
} |
} // namespace |