Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: base/file_util_win.cc

Issue 1763008: Windows: Make file_util::Delete("c:\\foo_dir", false) work correctly. Add more unit tests for Delete (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: re-upload patch set 4 Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/file_util_unittest.cc ('k') | chrome/installer/util/copy_tree_work_item_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 <propvarutil.h> 8 #include <propvarutil.h>
9 #include <shellapi.h> 9 #include <shellapi.h>
10 #include <shlobj.h> 10 #include <shlobj.h>
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 FindClose(find_handle); 66 FindClose(find_handle);
67 } 67 }
68 68
69 return file_count; 69 return file_count;
70 } 70 }
71 71
72 bool Delete(const FilePath& path, bool recursive) { 72 bool Delete(const FilePath& path, bool recursive) {
73 if (path.value().length() >= MAX_PATH) 73 if (path.value().length() >= MAX_PATH)
74 return false; 74 return false;
75 75
76 // If we're not recursing use DeleteFile; it should be faster. DeleteFile 76 if (!recursive) {
77 // fails if passed a directory though, which is why we fall through on 77 // If not recursing, then first check to see if |path| is a directory.
78 // failure to the SHFileOperation. 78 // If it is, then remove it with RemoveDirectory.
79 if (!recursive && DeleteFile(path.value().c_str()) != 0) 79 FileInfo file_info;
80 return true; 80 if (GetFileInfo(path, &file_info) && file_info.is_directory)
81 return RemoveDirectory(path.value().c_str()) != 0;
82
83 // Otherwise, it's a file, wildcard or non-existant. Try DeleteFile first
84 // because it should be faster. If DeleteFile fails, then we fall through
85 // to SHFileOperation, which will do the right thing.
86 if (DeleteFile(path.value().c_str()) != 0)
87 return true;
88 }
81 89
82 // SHFILEOPSTRUCT wants the path to be terminated with two NULLs, 90 // SHFILEOPSTRUCT wants the path to be terminated with two NULLs,
83 // so we have to use wcscpy because wcscpy_s writes non-NULLs 91 // so we have to use wcscpy because wcscpy_s writes non-NULLs
84 // into the rest of the buffer. 92 // into the rest of the buffer.
85 wchar_t double_terminated_path[MAX_PATH + 1] = {0}; 93 wchar_t double_terminated_path[MAX_PATH + 1] = {0};
86 #pragma warning(suppress:4996) // don't complain about wcscpy deprecation 94 #pragma warning(suppress:4996) // don't complain about wcscpy deprecation
87 wcscpy(double_terminated_path, path.value().c_str()); 95 wcscpy(double_terminated_path, path.value().c_str());
88 96
89 SHFILEOPSTRUCT file_operation = {0}; 97 SHFILEOPSTRUCT file_operation = {0};
90 file_operation.wFunc = FO_DELETE; 98 file_operation.wFunc = FO_DELETE;
91 file_operation.pFrom = double_terminated_path; 99 file_operation.pFrom = double_terminated_path;
92 file_operation.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION; 100 file_operation.fFlags = FOF_NOERRORUI | FOF_SILENT | FOF_NOCONFIRMATION;
93 if (!recursive) 101 if (!recursive)
94 file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY; 102 file_operation.fFlags |= FOF_NORECURSION | FOF_FILESONLY;
95 int err = SHFileOperation(&file_operation); 103 int err = SHFileOperation(&file_operation);
96 // Some versions of Windows return ERROR_FILE_NOT_FOUND when 104 // Some versions of Windows return ERROR_FILE_NOT_FOUND (0x2) when deleting
97 // deleting an empty directory. 105 // an empty directory and some return 0x402 when they should be returning
98 return (err == 0 || err == ERROR_FILE_NOT_FOUND); 106 // ERROR_FILE_NOT_FOUND. MSDN says Vista and up won't return 0x402.
107 return (err == 0 || err == ERROR_FILE_NOT_FOUND || err == 0x402);
99 } 108 }
100 109
101 bool DeleteAfterReboot(const FilePath& path) { 110 bool DeleteAfterReboot(const FilePath& path) {
102 if (path.value().length() >= MAX_PATH) 111 if (path.value().length() >= MAX_PATH)
103 return false; 112 return false;
104 113
105 return MoveFileEx(path.value().c_str(), NULL, 114 return MoveFileEx(path.value().c_str(), NULL,
106 MOVEFILE_DELAY_UNTIL_REBOOT | 115 MOVEFILE_DELAY_UNTIL_REBOOT |
107 MOVEFILE_REPLACE_EXISTING) != FALSE; 116 MOVEFILE_REPLACE_EXISTING) != FALSE;
108 } 117 }
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 return false; 602 return false;
594 } 603 }
595 } else { 604 } else {
596 LOG(INFO) << "::CreateDirectory() worked."; 605 LOG(INFO) << "::CreateDirectory() worked.";
597 return true; 606 return true;
598 } 607 }
599 } 608 }
600 609
601 bool GetFileInfo(const FilePath& file_path, FileInfo* results) { 610 bool GetFileInfo(const FilePath& file_path, FileInfo* results) {
602 WIN32_FILE_ATTRIBUTE_DATA attr; 611 WIN32_FILE_ATTRIBUTE_DATA attr;
603 if (!GetFileAttributesEx(file_path.ToWStringHack().c_str(), 612 if (!GetFileAttributesEx(file_path.value().c_str(),
604 GetFileExInfoStandard, &attr)) { 613 GetFileExInfoStandard, &attr)) {
605 return false; 614 return false;
606 } 615 }
607 616
608 ULARGE_INTEGER size; 617 ULARGE_INTEGER size;
609 size.HighPart = attr.nFileSizeHigh; 618 size.HighPart = attr.nFileSizeHigh;
610 size.LowPart = attr.nFileSizeLow; 619 size.LowPart = attr.nFileSizeLow;
611 results->size = size.QuadPart; 620 results->size = size.QuadPart;
612 621
613 results->is_directory = 622 results->is_directory =
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 } 899 }
891 900
892 bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info, 901 bool HasFileBeenModifiedSince(const FileEnumerator::FindInfo& find_info,
893 const base::Time& cutoff_time) { 902 const base::Time& cutoff_time) {
894 long result = CompareFileTime(&find_info.ftLastWriteTime, 903 long result = CompareFileTime(&find_info.ftLastWriteTime,
895 &cutoff_time.ToFileTime()); 904 &cutoff_time.ToFileTime());
896 return result == 1 || result == 0; 905 return result == 1 || result == 0;
897 } 906 }
898 907
899 } // namespace file_util 908 } // namespace file_util
OLDNEW
« no previous file with comments | « base/file_util_unittest.cc ('k') | chrome/installer/util/copy_tree_work_item_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698