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(HOST_OS_WINDOWS) | 6 #if defined(HOST_OS_WINDOWS) |
7 | 7 |
8 #include "bin/directory.h" | 8 #include "bin/directory.h" |
9 #include "bin/file.h" | 9 #include "bin/file.h" |
10 #include "bin/utils.h" | 10 #include "bin/utils.h" |
11 #include "bin/utils_win.h" | 11 #include "bin/utils_win.h" |
12 | 12 |
13 #include <errno.h> // NOLINT | 13 #include <errno.h> // NOLINT |
14 #include <sys/stat.h> // NOLINT | 14 #include <sys/stat.h> // NOLINT |
15 | 15 |
16 #include "bin/dartutils.h" | 16 #include "bin/dartutils.h" |
17 #include "bin/log.h" | 17 #include "bin/log.h" |
18 | 18 |
19 #undef DeleteFile | 19 #undef DeleteFile |
20 | 20 |
21 #define MAX_LONG_PATH 32767 | 21 #define MAX_LONG_PATH 32767 |
22 | 22 |
23 namespace dart { | 23 namespace dart { |
24 namespace bin { | 24 namespace bin { |
25 | 25 |
26 PathBuffer::PathBuffer() : length_(0) { | 26 PathBuffer::PathBuffer() : length_(0) { |
27 data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT | 27 data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT |
28 } | 28 } |
29 | 29 |
30 | |
31 PathBuffer::~PathBuffer() { | 30 PathBuffer::~PathBuffer() { |
32 free(data_); | 31 free(data_); |
33 } | 32 } |
34 | 33 |
35 | |
36 char* PathBuffer::AsString() const { | 34 char* PathBuffer::AsString() const { |
37 UNREACHABLE(); | 35 UNREACHABLE(); |
38 return NULL; | 36 return NULL; |
39 } | 37 } |
40 | 38 |
41 | |
42 wchar_t* PathBuffer::AsStringW() const { | 39 wchar_t* PathBuffer::AsStringW() const { |
43 return reinterpret_cast<wchar_t*>(data_); | 40 return reinterpret_cast<wchar_t*>(data_); |
44 } | 41 } |
45 | 42 |
46 | |
47 const char* PathBuffer::AsScopedString() const { | 43 const char* PathBuffer::AsScopedString() const { |
48 return StringUtilsWin::WideToUtf8(AsStringW()); | 44 return StringUtilsWin::WideToUtf8(AsStringW()); |
49 } | 45 } |
50 | 46 |
51 | |
52 bool PathBuffer::Add(const char* name) { | 47 bool PathBuffer::Add(const char* name) { |
53 Utf8ToWideScope wide_name(name); | 48 Utf8ToWideScope wide_name(name); |
54 return AddW(wide_name.wide()); | 49 return AddW(wide_name.wide()); |
55 } | 50 } |
56 | 51 |
57 | |
58 bool PathBuffer::AddW(const wchar_t* name) { | 52 bool PathBuffer::AddW(const wchar_t* name) { |
59 wchar_t* data = AsStringW(); | 53 wchar_t* data = AsStringW(); |
60 int written = | 54 int written = |
61 _snwprintf(data + length_, MAX_LONG_PATH - length_, L"%s", name); | 55 _snwprintf(data + length_, MAX_LONG_PATH - length_, L"%s", name); |
62 data[MAX_LONG_PATH] = L'\0'; | 56 data[MAX_LONG_PATH] = L'\0'; |
63 if ((written <= MAX_LONG_PATH - length_) && (written >= 0) && | 57 if ((written <= MAX_LONG_PATH - length_) && (written >= 0) && |
64 (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) { | 58 (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) { |
65 length_ += written; | 59 length_ += written; |
66 return true; | 60 return true; |
67 } else { | 61 } else { |
68 SetLastError(ERROR_BUFFER_OVERFLOW); | 62 SetLastError(ERROR_BUFFER_OVERFLOW); |
69 return false; | 63 return false; |
70 } | 64 } |
71 } | 65 } |
72 | 66 |
73 | |
74 void PathBuffer::Reset(intptr_t new_length) { | 67 void PathBuffer::Reset(intptr_t new_length) { |
75 length_ = new_length; | 68 length_ = new_length; |
76 AsStringW()[length_] = L'\0'; | 69 AsStringW()[length_] = L'\0'; |
77 } | 70 } |
78 | 71 |
79 | |
80 // If link_name points to a link, IsBrokenLink will return true if link_name | 72 // If link_name points to a link, IsBrokenLink will return true if link_name |
81 // points to an invalid target. | 73 // points to an invalid target. |
82 static bool IsBrokenLink(const wchar_t* link_name) { | 74 static bool IsBrokenLink(const wchar_t* link_name) { |
83 HANDLE handle = CreateFileW( | 75 HANDLE handle = CreateFileW( |
84 link_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 76 link_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
85 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | 77 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
86 if (handle == INVALID_HANDLE_VALUE) { | 78 if (handle == INVALID_HANDLE_VALUE) { |
87 return true; | 79 return true; |
88 } else { | 80 } else { |
89 CloseHandle(handle); | 81 CloseHandle(handle); |
90 return false; | 82 return false; |
91 } | 83 } |
92 } | 84 } |
93 | 85 |
94 | |
95 // A linked list structure holding a link target's unique file system ID. | 86 // A linked list structure holding a link target's unique file system ID. |
96 // Used to detect loops in the file system when listing recursively. | 87 // Used to detect loops in the file system when listing recursively. |
97 struct LinkList { | 88 struct LinkList { |
98 DWORD volume; | 89 DWORD volume; |
99 DWORD id_low; | 90 DWORD id_low; |
100 DWORD id_high; | 91 DWORD id_high; |
101 LinkList* next; | 92 LinkList* next; |
102 }; | 93 }; |
103 | 94 |
104 // Forward declarations. | 95 // Forward declarations. |
105 static bool DeleteRecursively(PathBuffer* path); | 96 static bool DeleteRecursively(PathBuffer* path); |
106 | 97 |
107 | |
108 static ListType HandleFindFile(DirectoryListing* listing, | 98 static ListType HandleFindFile(DirectoryListing* listing, |
109 DirectoryListingEntry* entry, | 99 DirectoryListingEntry* entry, |
110 const WIN32_FIND_DATAW& find_file_data) { | 100 const WIN32_FIND_DATAW& find_file_data) { |
111 if (!listing->path_buffer().AddW(find_file_data.cFileName)) { | 101 if (!listing->path_buffer().AddW(find_file_data.cFileName)) { |
112 return kListError; | 102 return kListError; |
113 } | 103 } |
114 DWORD attributes = find_file_data.dwFileAttributes; | 104 DWORD attributes = find_file_data.dwFileAttributes; |
115 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 105 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
116 if (!listing->follow_links()) { | 106 if (!listing->follow_links()) { |
117 return kListLink; | 107 return kListLink; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 if ((wcscmp(find_file_data.cFileName, L".") == 0) || | 153 if ((wcscmp(find_file_data.cFileName, L".") == 0) || |
164 (wcscmp(find_file_data.cFileName, L"..") == 0)) { | 154 (wcscmp(find_file_data.cFileName, L"..") == 0)) { |
165 return entry->Next(listing); | 155 return entry->Next(listing); |
166 } | 156 } |
167 return kListDirectory; | 157 return kListDirectory; |
168 } else { | 158 } else { |
169 return kListFile; | 159 return kListFile; |
170 } | 160 } |
171 } | 161 } |
172 | 162 |
173 | |
174 ListType DirectoryListingEntry::Next(DirectoryListing* listing) { | 163 ListType DirectoryListingEntry::Next(DirectoryListing* listing) { |
175 if (done_) { | 164 if (done_) { |
176 return kListDone; | 165 return kListDone; |
177 } | 166 } |
178 | 167 |
179 WIN32_FIND_DATAW find_file_data; | 168 WIN32_FIND_DATAW find_file_data; |
180 | 169 |
181 if (lister_ == 0) { | 170 if (lister_ == 0) { |
182 const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*"; | 171 const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*"; |
183 if (!listing->path_buffer().AddW(tail)) { | 172 if (!listing->path_buffer().AddW(tail)) { |
(...skipping 28 matching lines...) Expand all Loading... |
212 | 201 |
213 done_ = true; | 202 done_ = true; |
214 | 203 |
215 if (GetLastError() != ERROR_NO_MORE_FILES) { | 204 if (GetLastError() != ERROR_NO_MORE_FILES) { |
216 return kListError; | 205 return kListError; |
217 } | 206 } |
218 | 207 |
219 return kListDone; | 208 return kListDone; |
220 } | 209 } |
221 | 210 |
222 | |
223 DirectoryListingEntry::~DirectoryListingEntry() { | 211 DirectoryListingEntry::~DirectoryListingEntry() { |
224 ResetLink(); | 212 ResetLink(); |
225 if (lister_ != 0) { | 213 if (lister_ != 0) { |
226 FindClose(reinterpret_cast<HANDLE>(lister_)); | 214 FindClose(reinterpret_cast<HANDLE>(lister_)); |
227 } | 215 } |
228 } | 216 } |
229 | 217 |
230 | |
231 void DirectoryListingEntry::ResetLink() { | 218 void DirectoryListingEntry::ResetLink() { |
232 if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) { | 219 if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) { |
233 delete link_; | 220 delete link_; |
234 link_ = NULL; | 221 link_ = NULL; |
235 } | 222 } |
236 if (parent_ != NULL) { | 223 if (parent_ != NULL) { |
237 link_ = parent_->link_; | 224 link_ = parent_->link_; |
238 } | 225 } |
239 } | 226 } |
240 | 227 |
241 | |
242 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) { | 228 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) { |
243 if (!path->AddW(file_name)) { | 229 if (!path->AddW(file_name)) { |
244 return false; | 230 return false; |
245 } | 231 } |
246 | 232 |
247 if (DeleteFileW(path->AsStringW()) != 0) { | 233 if (DeleteFileW(path->AsStringW()) != 0) { |
248 return true; | 234 return true; |
249 } | 235 } |
250 | 236 |
251 // If we failed because the file is read-only, make it writeable and try | 237 // If we failed because the file is read-only, make it writeable and try |
(...skipping 12 matching lines...) Expand all Loading... |
264 return false; | 250 return false; |
265 } | 251 } |
266 | 252 |
267 return DeleteFileW(path->AsStringW()) != 0; | 253 return DeleteFileW(path->AsStringW()) != 0; |
268 } | 254 } |
269 } | 255 } |
270 | 256 |
271 return false; | 257 return false; |
272 } | 258 } |
273 | 259 |
274 | |
275 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { | 260 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { |
276 if ((wcscmp(dir_name, L".") == 0) || (wcscmp(dir_name, L"..") == 0)) { | 261 if ((wcscmp(dir_name, L".") == 0) || (wcscmp(dir_name, L"..") == 0)) { |
277 return true; | 262 return true; |
278 } | 263 } |
279 return path->AddW(dir_name) && DeleteRecursively(path); | 264 return path->AddW(dir_name) && DeleteRecursively(path); |
280 } | 265 } |
281 | 266 |
282 | |
283 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { | 267 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { |
284 DWORD attributes = find_file_data->dwFileAttributes; | 268 DWORD attributes = find_file_data->dwFileAttributes; |
285 | 269 |
286 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 270 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
287 return DeleteDir(find_file_data->cFileName, path); | 271 return DeleteDir(find_file_data->cFileName, path); |
288 } else { | 272 } else { |
289 return DeleteFile(find_file_data->cFileName, path); | 273 return DeleteFile(find_file_data->cFileName, path); |
290 } | 274 } |
291 } | 275 } |
292 | 276 |
293 | |
294 static bool DeleteRecursively(PathBuffer* path) { | 277 static bool DeleteRecursively(PathBuffer* path) { |
295 DWORD attributes = GetFileAttributesW(path->AsStringW()); | 278 DWORD attributes = GetFileAttributesW(path->AsStringW()); |
296 if (attributes == INVALID_FILE_ATTRIBUTES) { | 279 if (attributes == INVALID_FILE_ATTRIBUTES) { |
297 return false; | 280 return false; |
298 } | 281 } |
299 // If the directory is a junction, it's pointing to some other place in the | 282 // If the directory is a junction, it's pointing to some other place in the |
300 // filesystem that we do not want to recurse into. | 283 // filesystem that we do not want to recurse into. |
301 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 284 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
302 // Just delete the junction itself. | 285 // Just delete the junction itself. |
303 return RemoveDirectoryW(path->AsStringW()) != 0; | 286 return RemoveDirectoryW(path->AsStringW()) != 0; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 if (last_error != ERROR_NO_MORE_FILES) { | 318 if (last_error != ERROR_NO_MORE_FILES) { |
336 // Unexpected error, set and return. | 319 // Unexpected error, set and return. |
337 SetLastError(last_error); | 320 SetLastError(last_error); |
338 return false; | 321 return false; |
339 } | 322 } |
340 // All content deleted succesfully, try to delete directory. | 323 // All content deleted succesfully, try to delete directory. |
341 path->Reset(path_length - 1); // Drop the "\" from the end of the path. | 324 path->Reset(path_length - 1); // Drop the "\" from the end of the path. |
342 return RemoveDirectoryW(path->AsStringW()) != 0; | 325 return RemoveDirectoryW(path->AsStringW()) != 0; |
343 } | 326 } |
344 | 327 |
345 | |
346 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { | 328 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { |
347 DWORD attributes = GetFileAttributesW(dir_name); | 329 DWORD attributes = GetFileAttributesW(dir_name); |
348 if (attributes == INVALID_FILE_ATTRIBUTES) { | 330 if (attributes == INVALID_FILE_ATTRIBUTES) { |
349 DWORD last_error = GetLastError(); | 331 DWORD last_error = GetLastError(); |
350 if ((last_error == ERROR_FILE_NOT_FOUND) || | 332 if ((last_error == ERROR_FILE_NOT_FOUND) || |
351 (last_error == ERROR_PATH_NOT_FOUND)) { | 333 (last_error == ERROR_PATH_NOT_FOUND)) { |
352 return Directory::DOES_NOT_EXIST; | 334 return Directory::DOES_NOT_EXIST; |
353 } else { | 335 } else { |
354 // We might not be able to get the file attributes for other | 336 // We might not be able to get the file attributes for other |
355 // reasons such as lack of permissions. In that case we do | 337 // reasons such as lack of permissions. In that case we do |
356 // not know if the directory exists. | 338 // not know if the directory exists. |
357 return Directory::UNKNOWN; | 339 return Directory::UNKNOWN; |
358 } | 340 } |
359 } | 341 } |
360 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | 342 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
361 exists = exists && !IsBrokenLink(dir_name); | 343 exists = exists && !IsBrokenLink(dir_name); |
362 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; | 344 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; |
363 } | 345 } |
364 | 346 |
365 | |
366 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 347 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
367 Utf8ToWideScope system_name(dir_name); | 348 Utf8ToWideScope system_name(dir_name); |
368 return ExistsHelper(system_name.wide()); | 349 return ExistsHelper(system_name.wide()); |
369 } | 350 } |
370 | 351 |
371 | |
372 char* Directory::CurrentNoScope() { | 352 char* Directory::CurrentNoScope() { |
373 int length = GetCurrentDirectoryW(0, NULL); | 353 int length = GetCurrentDirectoryW(0, NULL); |
374 if (length == 0) { | 354 if (length == 0) { |
375 return NULL; | 355 return NULL; |
376 } | 356 } |
377 wchar_t* current = new wchar_t[length + 1]; | 357 wchar_t* current = new wchar_t[length + 1]; |
378 GetCurrentDirectoryW(length + 1, current); | 358 GetCurrentDirectoryW(length + 1, current); |
379 int utf8_len = | 359 int utf8_len = |
380 WideCharToMultiByte(CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL); | 360 WideCharToMultiByte(CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL); |
381 char* result = reinterpret_cast<char*>(malloc(utf8_len)); | 361 char* result = reinterpret_cast<char*>(malloc(utf8_len)); |
382 WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL); | 362 WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL); |
383 delete[] current; | 363 delete[] current; |
384 return result; | 364 return result; |
385 } | 365 } |
386 | 366 |
387 | |
388 const char* Directory::Current() { | 367 const char* Directory::Current() { |
389 int length = GetCurrentDirectoryW(0, NULL); | 368 int length = GetCurrentDirectoryW(0, NULL); |
390 if (length == 0) { | 369 if (length == 0) { |
391 return NULL; | 370 return NULL; |
392 } | 371 } |
393 wchar_t* current; | 372 wchar_t* current; |
394 current = reinterpret_cast<wchar_t*>( | 373 current = reinterpret_cast<wchar_t*>( |
395 Dart_ScopeAllocate((length + 1) * sizeof(*current))); | 374 Dart_ScopeAllocate((length + 1) * sizeof(*current))); |
396 GetCurrentDirectoryW(length + 1, current); | 375 GetCurrentDirectoryW(length + 1, current); |
397 return StringUtilsWin::WideToUtf8(current); | 376 return StringUtilsWin::WideToUtf8(current); |
398 } | 377 } |
399 | 378 |
400 | |
401 bool Directory::SetCurrent(const char* path) { | 379 bool Directory::SetCurrent(const char* path) { |
402 Utf8ToWideScope system_path(path); | 380 Utf8ToWideScope system_path(path); |
403 bool result = SetCurrentDirectoryW(system_path.wide()) != 0; | 381 bool result = SetCurrentDirectoryW(system_path.wide()) != 0; |
404 return result; | 382 return result; |
405 } | 383 } |
406 | 384 |
407 | |
408 bool Directory::Create(const char* dir_name) { | 385 bool Directory::Create(const char* dir_name) { |
409 Utf8ToWideScope system_name(dir_name); | 386 Utf8ToWideScope system_name(dir_name); |
410 int create_status = CreateDirectoryW(system_name.wide(), NULL); | 387 int create_status = CreateDirectoryW(system_name.wide(), NULL); |
411 // If the directory already existed, treat it as a success. | 388 // If the directory already existed, treat it as a success. |
412 if ((create_status == 0) && (GetLastError() == ERROR_ALREADY_EXISTS) && | 389 if ((create_status == 0) && (GetLastError() == ERROR_ALREADY_EXISTS) && |
413 (ExistsHelper(system_name.wide()) == EXISTS)) { | 390 (ExistsHelper(system_name.wide()) == EXISTS)) { |
414 return true; | 391 return true; |
415 } | 392 } |
416 return (create_status != 0); | 393 return (create_status != 0); |
417 } | 394 } |
418 | 395 |
419 | |
420 const char* Directory::SystemTemp() { | 396 const char* Directory::SystemTemp() { |
421 PathBuffer path; | 397 PathBuffer path; |
422 // Remove \ at end. | 398 // Remove \ at end. |
423 path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1); | 399 path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1); |
424 return path.AsScopedString(); | 400 return path.AsScopedString(); |
425 } | 401 } |
426 | 402 |
427 | |
428 const char* Directory::CreateTemp(const char* prefix) { | 403 const char* Directory::CreateTemp(const char* prefix) { |
429 // Returns a new, unused directory name, adding characters to the | 404 // Returns a new, unused directory name, adding characters to the |
430 // end of prefix. | 405 // end of prefix. |
431 // Creates this directory, with a default security | 406 // Creates this directory, with a default security |
432 // descriptor inherited from its parent directory. | 407 // descriptor inherited from its parent directory. |
433 // The return value is Dart_ScopeAllocated. | 408 // The return value is Dart_ScopeAllocated. |
434 PathBuffer path; | 409 PathBuffer path; |
435 Utf8ToWideScope system_prefix(prefix); | 410 Utf8ToWideScope system_prefix(prefix); |
436 if (!path.AddW(system_prefix.wide())) { | 411 if (!path.AddW(system_prefix.wide())) { |
437 return NULL; | 412 return NULL; |
(...skipping 19 matching lines...) Expand all Loading... |
457 if (!path.AddW(reinterpret_cast<wchar_t*>(uuid_string))) { | 432 if (!path.AddW(reinterpret_cast<wchar_t*>(uuid_string))) { |
458 return NULL; | 433 return NULL; |
459 } | 434 } |
460 RpcStringFreeW(&uuid_string); | 435 RpcStringFreeW(&uuid_string); |
461 if (!CreateDirectoryW(path.AsStringW(), NULL)) { | 436 if (!CreateDirectoryW(path.AsStringW(), NULL)) { |
462 return NULL; | 437 return NULL; |
463 } | 438 } |
464 return path.AsScopedString(); | 439 return path.AsScopedString(); |
465 } | 440 } |
466 | 441 |
467 | |
468 bool Directory::Delete(const char* dir_name, bool recursive) { | 442 bool Directory::Delete(const char* dir_name, bool recursive) { |
469 bool result = false; | 443 bool result = false; |
470 Utf8ToWideScope system_dir_name(dir_name); | 444 Utf8ToWideScope system_dir_name(dir_name); |
471 if (!recursive) { | 445 if (!recursive) { |
472 if (File::GetType(dir_name, true) == File::kIsDirectory) { | 446 if (File::GetType(dir_name, true) == File::kIsDirectory) { |
473 result = (RemoveDirectoryW(system_dir_name.wide()) != 0); | 447 result = (RemoveDirectoryW(system_dir_name.wide()) != 0); |
474 } else { | 448 } else { |
475 SetLastError(ERROR_FILE_NOT_FOUND); | 449 SetLastError(ERROR_FILE_NOT_FOUND); |
476 } | 450 } |
477 } else { | 451 } else { |
478 PathBuffer path; | 452 PathBuffer path; |
479 if (path.AddW(system_dir_name.wide())) { | 453 if (path.AddW(system_dir_name.wide())) { |
480 result = DeleteRecursively(&path); | 454 result = DeleteRecursively(&path); |
481 } | 455 } |
482 } | 456 } |
483 return result; | 457 return result; |
484 } | 458 } |
485 | 459 |
486 | |
487 bool Directory::Rename(const char* path, const char* new_path) { | 460 bool Directory::Rename(const char* path, const char* new_path) { |
488 Utf8ToWideScope system_path(path); | 461 Utf8ToWideScope system_path(path); |
489 Utf8ToWideScope system_new_path(new_path); | 462 Utf8ToWideScope system_new_path(new_path); |
490 ExistsResult exists = ExistsHelper(system_path.wide()); | 463 ExistsResult exists = ExistsHelper(system_path.wide()); |
491 if (exists != EXISTS) { | 464 if (exists != EXISTS) { |
492 return false; | 465 return false; |
493 } | 466 } |
494 ExistsResult new_exists = ExistsHelper(system_new_path.wide()); | 467 ExistsResult new_exists = ExistsHelper(system_new_path.wide()); |
495 // MoveFile does not allow replacing existing directories. Therefore, | 468 // MoveFile does not allow replacing existing directories. Therefore, |
496 // if the new_path is currently a directory we need to delete it | 469 // if the new_path is currently a directory we need to delete it |
497 // first. | 470 // first. |
498 if (new_exists == EXISTS) { | 471 if (new_exists == EXISTS) { |
499 bool success = Delete(new_path, true); | 472 bool success = Delete(new_path, true); |
500 if (!success) { | 473 if (!success) { |
501 return false; | 474 return false; |
502 } | 475 } |
503 } | 476 } |
504 DWORD flags = MOVEFILE_WRITE_THROUGH; | 477 DWORD flags = MOVEFILE_WRITE_THROUGH; |
505 int move_status = | 478 int move_status = |
506 MoveFileExW(system_path.wide(), system_new_path.wide(), flags); | 479 MoveFileExW(system_path.wide(), system_new_path.wide(), flags); |
507 return (move_status != 0); | 480 return (move_status != 0); |
508 } | 481 } |
509 | 482 |
510 } // namespace bin | 483 } // namespace bin |
511 } // namespace dart | 484 } // namespace dart |
512 | 485 |
513 #endif // defined(HOST_OS_WINDOWS) | 486 #endif // defined(HOST_OS_WINDOWS) |
OLD | NEW |