summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/file_util.h4
-rw-r--r--base/file_util_win.cc59
2 files changed, 20 insertions, 43 deletions
diff --git a/base/file_util.h b/base/file_util.h
index 150b629..8594d28 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -346,8 +346,8 @@ class FileEnumerator {
DISALLOW_EVIL_CONSTRUCTORS(FileEnumerator);
};
-// Renames a file using the MoveFileEx API and ensures that the target file gets
-// the correct security descriptor in the new path.
+// Renames a file using the SHFileOperation API to ensure that the target file
+// gets the correct default security descriptor in the new path.
bool RenameFileAndResetSecurityDescriptor(
const std::wstring& source_file_path,
const std::wstring& target_file_path);
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 9c34ab3..9d775f0 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -535,47 +535,24 @@ int WriteFile(const std::wstring& filename, const char* data, int size) {
bool RenameFileAndResetSecurityDescriptor(
const std::wstring& source_file_path,
const std::wstring& target_file_path) {
- // The MoveFile API does not reset the security descriptor on the target
- // file. To ensure that the target file gets the correct security descriptor
- // we create the target file initially in the target path, read its security
- // descriptor and stamp this descriptor on the target file after the MoveFile
- // API completes.
- ScopedHandle temp_file_handle_for_security_desc(
- CreateFileW(target_file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL, OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
- NULL));
- if (!temp_file_handle_for_security_desc.IsValid())
- return false;
-
- // Check how much we should allocate for the security descriptor.
- unsigned long security_descriptor_size_in_bytes = 0;
- GetFileSecurity(target_file_path.c_str(), DACL_SECURITY_INFORMATION, NULL, 0,
- &security_descriptor_size_in_bytes);
- if (ERROR_INSUFFICIENT_BUFFER != GetLastError() ||
- security_descriptor_size_in_bytes == 0)
- return false;
-
- scoped_array<char> security_descriptor(
- new char[security_descriptor_size_in_bytes]);
-
- if (!GetFileSecurity(target_file_path.c_str(), DACL_SECURITY_INFORMATION,
- security_descriptor.get(),
- security_descriptor_size_in_bytes,
- &security_descriptor_size_in_bytes)) {
- return false;
- }
-
- temp_file_handle_for_security_desc.Set(INVALID_HANDLE_VALUE);
-
- if (!MoveFileEx(source_file_path.c_str(), target_file_path.c_str(),
- MOVEFILE_COPY_ALLOWED)) {
- return false;
- }
-
- return !!SetFileSecurity(target_file_path.c_str(),
- DACL_SECURITY_INFORMATION,
- security_descriptor.get());
+ // The parameters to SHFileOperation must be terminated with 2 NULL chars.
+ std::wstring source = source_file_path;
+ std::wstring target = target_file_path;
+
+ source.append(1, L'\0');
+ target.append(1, L'\0');
+
+ SHFILEOPSTRUCT move_info = {0};
+ move_info.wFunc = FO_MOVE;
+ move_info.pFrom = source.c_str();
+ move_info.pTo = target.c_str();
+ move_info.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI |
+ FOF_NOCONFIRMMKDIR | FOF_NOCOPYSECURITYATTRIBS;
+
+ if (0 != SHFileOperation(&move_info))
+ return false;
+
+ return true;
}
// Gets the current working directory for the process.