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 |