| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <psapi.h> | 8 #include <psapi.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #include <shlobj.h> | 10 #include <shlobj.h> |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 FilePath* new_temp_path) { | 396 FilePath* new_temp_path) { |
| 397 base::ThreadRestrictions::AssertIOAllowed(); | 397 base::ThreadRestrictions::AssertIOAllowed(); |
| 398 | 398 |
| 399 FilePath system_temp_dir; | 399 FilePath system_temp_dir; |
| 400 if (!GetTempDir(&system_temp_dir)) | 400 if (!GetTempDir(&system_temp_dir)) |
| 401 return false; | 401 return false; |
| 402 | 402 |
| 403 return CreateTemporaryDirInDir(system_temp_dir, prefix, new_temp_path); | 403 return CreateTemporaryDirInDir(system_temp_dir, prefix, new_temp_path); |
| 404 } | 404 } |
| 405 | 405 |
| 406 bool CreateDirectory(const FilePath& full_path) { | 406 bool CreateDirectoryAndGetError(const FilePath& full_path, |
| 407 base::PlatformFileError* error) { |
| 407 base::ThreadRestrictions::AssertIOAllowed(); | 408 base::ThreadRestrictions::AssertIOAllowed(); |
| 408 | 409 |
| 409 // If the path exists, we've succeeded if it's a directory, failed otherwise. | 410 // If the path exists, we've succeeded if it's a directory, failed otherwise. |
| 410 const wchar_t* full_path_str = full_path.value().c_str(); | 411 const wchar_t* full_path_str = full_path.value().c_str(); |
| 411 DWORD fileattr = ::GetFileAttributes(full_path_str); | 412 DWORD fileattr = ::GetFileAttributes(full_path_str); |
| 412 if (fileattr != INVALID_FILE_ATTRIBUTES) { | 413 if (fileattr != INVALID_FILE_ATTRIBUTES) { |
| 413 if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 414 if ((fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 414 DVLOG(1) << "CreateDirectory(" << full_path_str << "), " | 415 DVLOG(1) << "CreateDirectory(" << full_path_str << "), " |
| 415 << "directory already exists."; | 416 << "directory already exists."; |
| 416 return true; | 417 return true; |
| 417 } | 418 } |
| 418 DLOG(WARNING) << "CreateDirectory(" << full_path_str << "), " | 419 DLOG(WARNING) << "CreateDirectory(" << full_path_str << "), " |
| 419 << "conflicts with existing file."; | 420 << "conflicts with existing file."; |
| 420 return false; | 421 return false; |
| 421 } | 422 } |
| 422 | 423 |
| 423 // Invariant: Path does not exist as file or directory. | 424 // Invariant: Path does not exist as file or directory. |
| 424 | 425 |
| 425 // Attempt to create the parent recursively. This will immediately return | 426 // Attempt to create the parent recursively. This will immediately return |
| 426 // true if it already exists, otherwise will create all required parent | 427 // true if it already exists, otherwise will create all required parent |
| 427 // directories starting with the highest-level missing parent. | 428 // directories starting with the highest-level missing parent. |
| 428 FilePath parent_path(full_path.DirName()); | 429 FilePath parent_path(full_path.DirName()); |
| 429 if (parent_path.value() == full_path.value()) { | 430 if (parent_path.value() == full_path.value()) { |
| 430 return false; | 431 return false; |
| 431 } | 432 } |
| 432 if (!CreateDirectory(parent_path)) { | 433 if (!CreateDirectoryAndGetError(parent_path, error)) { |
| 433 DLOG(WARNING) << "Failed to create one of the parent directories."; | 434 DLOG(WARNING) << "Failed to create one of the parent directories."; |
| 434 return false; | 435 return false; |
| 435 } | 436 } |
| 436 | 437 |
| 437 if (!::CreateDirectory(full_path_str, NULL)) { | 438 if (!::CreateDirectory(full_path_str, NULL)) { |
| 438 DWORD error_code = ::GetLastError(); | 439 DWORD error_code = ::GetLastError(); |
| 439 if (error_code == ERROR_ALREADY_EXISTS && DirectoryExists(full_path)) { | 440 if (error_code == ERROR_ALREADY_EXISTS && DirectoryExists(full_path)) { |
| 440 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we | 441 // This error code ERROR_ALREADY_EXISTS doesn't indicate whether we |
| 441 // were racing with someone creating the same directory, or a file | 442 // were racing with someone creating the same directory, or a file |
| 442 // with the same path. If DirectoryExists() returns true, we lost the | 443 // with the same path. If DirectoryExists() returns true, we lost the |
| 443 // race to create the same directory. | 444 // race to create the same directory. |
| 444 return true; | 445 return true; |
| 445 } else { | 446 } else { |
| 447 if (error) |
| 448 *error = base::LastErrorToPlatformFileError(error_code); |
| 446 DLOG(WARNING) << "Failed to create directory " << full_path_str | 449 DLOG(WARNING) << "Failed to create directory " << full_path_str |
| 447 << ", last error is " << error_code << "."; | 450 << ", last error is " << error_code << "."; |
| 448 return false; | 451 return false; |
| 449 } | 452 } |
| 450 } else { | 453 } else { |
| 451 return true; | 454 return true; |
| 452 } | 455 } |
| 453 } | 456 } |
| 454 | 457 |
| 455 // TODO(rkc): Work out if we want to handle NTFS junctions here or not, handle | 458 // TODO(rkc): Work out if we want to handle NTFS junctions here or not, handle |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 | 731 |
| 729 // Length of |path| with path separator appended. | 732 // Length of |path| with path separator appended. |
| 730 size_t prefix = path.StripTrailingSeparators().value().size() + 1; | 733 size_t prefix = path.StripTrailingSeparators().value().size() + 1; |
| 731 // The whole path string must be shorter than MAX_PATH. That is, it must be | 734 // The whole path string must be shorter than MAX_PATH. That is, it must be |
| 732 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). | 735 // prefix + component_length < MAX_PATH (or equivalently, <= MAX_PATH - 1). |
| 733 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); | 736 int whole_path_limit = std::max(0, MAX_PATH - 1 - static_cast<int>(prefix)); |
| 734 return std::min(whole_path_limit, static_cast<int>(max_length)); | 737 return std::min(whole_path_limit, static_cast<int>(max_length)); |
| 735 } | 738 } |
| 736 | 739 |
| 737 } // namespace file_util | 740 } // namespace file_util |
| OLD | NEW |