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 |