summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
Diffstat (limited to 'base')
-rw-r--r--base/file_util_unittest.cc17
-rw-r--r--base/file_util_win.cc41
2 files changed, 55 insertions, 3 deletions
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 6d57e2c..7296113 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -1137,6 +1137,23 @@ TEST_F(FileUtilTest, CreateDirectoryTest) {
EXPECT_TRUE(file_util::Delete(test_root, true));
EXPECT_FALSE(file_util::PathExists(test_root));
EXPECT_FALSE(file_util::PathExists(test_path));
+
+ // Verify assumptions made by the Windows implementation:
+ // 1. The current directory always exists.
+ // 2. The root directory always exists.
+ ASSERT_TRUE(file_util::DirectoryExists(
+ FilePath(FilePath::kCurrentDirectory)));
+ FilePath top_level = test_root;
+ while (top_level != top_level.DirName()) {
+ top_level = top_level.DirName();
+ }
+ ASSERT_TRUE(file_util::DirectoryExists(top_level));
+
+ // Given these assumptions hold, it should be safe to
+ // test that "creating" these directories succeeds.
+ EXPECT_TRUE(file_util::CreateDirectory(
+ FilePath(FilePath::kCurrentDirectory)));
+ EXPECT_TRUE(file_util::CreateDirectory(top_level));
}
TEST_F(FileUtilTest, DetectDirectoryTest) {
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 9722e31..812a706 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -509,10 +509,45 @@ bool CreateNewTempDirectory(const FilePath::StringType& prefix,
}
bool CreateDirectory(const FilePath& full_path) {
- if (DirectoryExists(full_path))
+ // If the path exists, we've succeeded if it's a directory, failed otherwise.
+ const wchar_t* full_path_str = full_path.value().c_str();
+ DWORD fileattr = ::GetFileAttributes(full_path_str);
+ if (fileattr != INVALID_FILE_ATTRIBUTES) {
+ if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ DLOG(INFO) << "CreateDirectory(" << full_path_str << "), " <<
+ "directory already exists.";
+ return true;
+ } else {
+ LOG(WARNING) << "CreateDirectory(" << full_path_str << "), " <<
+ "conflicts with existing file.";
+ }
+ }
+
+ // Invariant: Path does not exist as file or directory.
+
+ // Attempt to create the parent recursively. This will immediately return
+ // true if it already exists, otherwise will create all required parent
+ // directories starting with the highest-level missing parent.
+ if (!CreateDirectory(full_path.DirName())) {
+ DLOG(WARNING) << "Failed to create one of the parent directories.";
+ return false;
+ }
+
+ if (!::CreateDirectory(full_path_str, NULL)) {
+ DWORD error_code = ::GetLastError();
+ if (error_code == ERROR_ALREADY_EXISTS && DirectoryExists(full_path)) {
+ // This error code doesn't indicate whether we were racing with someone
+ // creating the same directory, or a file with the same path, therefore
+ // we check.
+ return true;
+ } else {
+ LOG(WARNING) << "Failed to create directory " << full_path_str <<
+ ", le=" << error_code;
+ return false;
+ }
+ } else {
return true;
- int err = SHCreateDirectoryEx(NULL, full_path.value().c_str(), NULL);
- return err == ERROR_SUCCESS;
+ }
}
bool GetFileInfo(const FilePath& file_path, FileInfo* results) {