| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/directory.h" | 8 #include "bin/directory.h" |
| 9 | 9 |
| 10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 void Reset(int new_length) { | 45 void Reset(int new_length) { |
| 46 length = new_length; | 46 length = new_length; |
| 47 data[length] = L'\0'; | 47 data[length] = L'\0'; |
| 48 } | 48 } |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 | 51 |
| 52 // Forward declarations. | 52 // Forward declarations. |
| 53 static bool ListRecursively(PathBuffer* path, | 53 static bool ListRecursively(PathBuffer* path, |
| 54 bool recursive, | 54 bool recursive, |
| 55 bool follow_links, |
| 55 DirectoryListing* listing); | 56 DirectoryListing* listing); |
| 56 static bool DeleteRecursively(PathBuffer* path); | 57 static bool DeleteRecursively(PathBuffer* path); |
| 57 | 58 |
| 58 | 59 |
| 59 static void PostError(DirectoryListing* listing, | 60 static void PostError(DirectoryListing* listing, |
| 60 const wchar_t* dir_name) { | 61 const wchar_t* dir_name) { |
| 61 const char* utf8_path = StringUtils::WideToUtf8(dir_name); | 62 const char* utf8_path = StringUtils::WideToUtf8(dir_name); |
| 62 listing->HandleError(utf8_path); | 63 listing->HandleError(utf8_path); |
| 63 free(const_cast<char*>(utf8_path)); | 64 free(const_cast<char*>(utf8_path)); |
| 64 } | 65 } |
| 65 | 66 |
| 66 | 67 |
| 67 static bool HandleDir(wchar_t* dir_name, | 68 static bool HandleDir(wchar_t* dir_name, |
| 68 PathBuffer* path, | 69 PathBuffer* path, |
| 69 bool recursive, | 70 bool recursive, |
| 71 bool follow_links, |
| 70 DirectoryListing* listing) { | 72 DirectoryListing* listing) { |
| 71 if (wcscmp(dir_name, L".") == 0) return true; | 73 if (wcscmp(dir_name, L".") == 0) return true; |
| 72 if (wcscmp(dir_name, L"..") == 0) return true; | 74 if (wcscmp(dir_name, L"..") == 0) return true; |
| 73 if (!path->Add(dir_name)) { | 75 if (!path->Add(dir_name)) { |
| 74 PostError(listing, path->data); | 76 PostError(listing, path->data); |
| 75 return false; | 77 return false; |
| 76 } | 78 } |
| 77 char* utf8_path = StringUtils::WideToUtf8(path->data); | 79 char* utf8_path = StringUtils::WideToUtf8(path->data); |
| 78 bool ok = listing->HandleDirectory(utf8_path); | 80 bool ok = listing->HandleDirectory(utf8_path); |
| 79 free(utf8_path); | 81 free(utf8_path); |
| 80 return ok && (!recursive || ListRecursively(path, recursive, listing)); | 82 return ok && |
| 83 (!recursive || ListRecursively(path, recursive, follow_links, listing)); |
| 81 } | 84 } |
| 82 | 85 |
| 83 | 86 |
| 84 static bool HandleFile(wchar_t* file_name, | 87 static bool HandleFile(wchar_t* file_name, |
| 85 PathBuffer* path, | 88 PathBuffer* path, |
| 86 DirectoryListing* listing) { | 89 DirectoryListing* listing) { |
| 87 if (!path->Add(file_name)) { | 90 if (!path->Add(file_name)) { |
| 88 PostError(listing, path->data); | 91 PostError(listing, path->data); |
| 89 return false; | 92 return false; |
| 90 } | 93 } |
| 91 char* utf8_path = StringUtils::WideToUtf8(path->data); | 94 char* utf8_path = StringUtils::WideToUtf8(path->data); |
| 92 bool ok = listing->HandleFile(utf8_path); | 95 bool ok = listing->HandleFile(utf8_path); |
| 93 free(utf8_path); | 96 free(utf8_path); |
| 94 return ok; | 97 return ok; |
| 95 } | 98 } |
| 96 | 99 |
| 97 | 100 |
| 101 static bool HandleLink(wchar_t* link_name, |
| 102 PathBuffer* path, |
| 103 DirectoryListing* listing) { |
| 104 if (!path->Add(link_name)) { |
| 105 PostError(listing, path->data); |
| 106 return false; |
| 107 } |
| 108 char* utf8_path = StringUtils::WideToUtf8(path->data); |
| 109 bool ok = listing->HandleLink(utf8_path); |
| 110 free(utf8_path); |
| 111 return ok; |
| 112 } |
| 113 |
| 114 |
| 98 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data, | 115 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data, |
| 99 PathBuffer* path, | 116 PathBuffer* path, |
| 100 bool recursive, | 117 bool recursive, |
| 118 bool follow_links, |
| 101 DirectoryListing* listing) { | 119 DirectoryListing* listing) { |
| 102 DWORD attributes = find_file_data->dwFileAttributes; | 120 DWORD attributes = find_file_data->dwFileAttributes; |
| 103 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 121 if (!follow_links && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 122 return HandleLink(find_file_data->cFileName, path, listing); |
| 123 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 104 return HandleDir(find_file_data->cFileName, | 124 return HandleDir(find_file_data->cFileName, |
| 105 path, | 125 path, |
| 106 recursive, | 126 recursive, |
| 127 follow_links, |
| 107 listing); | 128 listing); |
| 108 } else { | 129 } else { |
| 109 return HandleFile(find_file_data->cFileName, path, listing); | 130 return HandleFile(find_file_data->cFileName, path, listing); |
| 110 } | 131 } |
| 111 } | 132 } |
| 112 | 133 |
| 113 | 134 |
| 114 static bool ListRecursively(PathBuffer* path, | 135 static bool ListRecursively(PathBuffer* path, |
| 115 bool recursive, | 136 bool recursive, |
| 137 bool follow_links, |
| 116 DirectoryListing* listing) { | 138 DirectoryListing* listing) { |
| 117 if (!path->Add(L"\\*")) { | 139 if (!path->Add(L"\\*")) { |
| 118 PostError(listing, path->data); | 140 PostError(listing, path->data); |
| 119 return false; | 141 return false; |
| 120 } | 142 } |
| 121 | 143 |
| 122 WIN32_FIND_DATAW find_file_data; | 144 WIN32_FIND_DATAW find_file_data; |
| 123 HANDLE find_handle = FindFirstFileW(path->data, &find_file_data); | 145 HANDLE find_handle = FindFirstFileW(path->data, &find_file_data); |
| 124 | 146 |
| 125 // Adjust the path by removing the '*' used for the search. | 147 // Adjust the path by removing the '*' used for the search. |
| 126 path->Reset(path->length - 1); | 148 path->Reset(path->length - 1); |
| 127 | 149 |
| 128 if (find_handle == INVALID_HANDLE_VALUE) { | 150 if (find_handle == INVALID_HANDLE_VALUE) { |
| 129 PostError(listing, path->data); | 151 PostError(listing, path->data); |
| 130 return false; | 152 return false; |
| 131 } | 153 } |
| 132 | 154 |
| 133 int path_length = path->length; | 155 int path_length = path->length; |
| 134 bool success = HandleEntry(&find_file_data, | 156 bool success = HandleEntry(&find_file_data, |
| 135 path, | 157 path, |
| 136 recursive, | 158 recursive, |
| 159 follow_links, |
| 137 listing); | 160 listing); |
| 138 | 161 |
| 139 while ((FindNextFileW(find_handle, &find_file_data) != 0)) { | 162 while ((FindNextFileW(find_handle, &find_file_data) != 0)) { |
| 140 path->Reset(path_length); // HandleEntry adds the entry name to path. | 163 path->Reset(path_length); // HandleEntry adds the entry name to path. |
| 141 success = HandleEntry(&find_file_data, | 164 success = HandleEntry(&find_file_data, |
| 142 path, | 165 path, |
| 143 recursive, | 166 recursive, |
| 167 follow_links, |
| 144 listing) && success; | 168 listing) && success; |
| 145 } | 169 } |
| 146 | 170 |
| 147 if (GetLastError() != ERROR_NO_MORE_FILES) { | 171 if (GetLastError() != ERROR_NO_MORE_FILES) { |
| 148 success = false; | 172 success = false; |
| 149 PostError(listing, path->data); | 173 PostError(listing, path->data); |
| 150 } | 174 } |
| 151 | 175 |
| 152 if (FindClose(find_handle) == 0) { | 176 if (FindClose(find_handle) == 0) { |
| 153 success = false; | 177 success = false; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 (RemoveDirectoryW(path->data) == 0)) { | 267 (RemoveDirectoryW(path->data) == 0)) { |
| 244 return false; | 268 return false; |
| 245 } | 269 } |
| 246 | 270 |
| 247 return success; | 271 return success; |
| 248 } | 272 } |
| 249 | 273 |
| 250 | 274 |
| 251 bool Directory::List(const char* dir_name, | 275 bool Directory::List(const char* dir_name, |
| 252 bool recursive, | 276 bool recursive, |
| 277 bool follow_links, |
| 253 DirectoryListing* listing) { | 278 DirectoryListing* listing) { |
| 254 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name); | 279 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name); |
| 255 PathBuffer path; | 280 PathBuffer path; |
| 256 if (!path.Add(system_name)) { | 281 if (!path.Add(system_name)) { |
| 257 PostError(listing, system_name); | 282 PostError(listing, system_name); |
| 258 return false; | 283 return false; |
| 259 } | 284 } |
| 260 free(const_cast<wchar_t*>(system_name)); | 285 free(const_cast<wchar_t*>(system_name)); |
| 261 return ListRecursively(&path, recursive, listing); | 286 return ListRecursively(&path, recursive, follow_links, listing); |
| 262 } | 287 } |
| 263 | 288 |
| 264 | 289 |
| 265 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { | 290 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { |
| 266 DWORD attributes = GetFileAttributesW(dir_name); | 291 DWORD attributes = GetFileAttributesW(dir_name); |
| 267 if (attributes == INVALID_FILE_ATTRIBUTES) { | 292 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 268 DWORD last_error = GetLastError(); | 293 DWORD last_error = GetLastError(); |
| 269 if (last_error == ERROR_FILE_NOT_FOUND || | 294 if (last_error == ERROR_FILE_NOT_FOUND || |
| 270 last_error == ERROR_PATH_NOT_FOUND) { | 295 last_error == ERROR_PATH_NOT_FOUND) { |
| 271 return Directory::DOES_NOT_EXIST; | 296 return Directory::DOES_NOT_EXIST; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 } | 419 } |
| 395 DWORD flags = MOVEFILE_WRITE_THROUGH; | 420 DWORD flags = MOVEFILE_WRITE_THROUGH; |
| 396 int move_status = | 421 int move_status = |
| 397 MoveFileExW(system_path, system_new_path, flags); | 422 MoveFileExW(system_path, system_new_path, flags); |
| 398 free(const_cast<wchar_t*>(system_path)); | 423 free(const_cast<wchar_t*>(system_path)); |
| 399 free(const_cast<wchar_t*>(system_new_path)); | 424 free(const_cast<wchar_t*>(system_new_path)); |
| 400 return (move_status != 0); | 425 return (move_status != 0); |
| 401 } | 426 } |
| 402 | 427 |
| 403 #endif // defined(TARGET_OS_WINDOWS) | 428 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |