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 #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 | 12 |
12 #include <errno.h> // NOLINT | 13 #include <errno.h> // NOLINT |
13 #include <sys/stat.h> // NOLINT | 14 #include <sys/stat.h> // NOLINT |
14 | 15 |
15 #include "bin/log.h" | 16 #include "bin/log.h" |
16 | 17 |
17 #undef DeleteFile | 18 #undef DeleteFile |
18 | 19 |
19 #define MAX_LONG_PATH 32767 | 20 #define MAX_LONG_PATH 32767 |
20 | 21 |
21 namespace dart { | 22 namespace dart { |
22 namespace bin { | 23 namespace bin { |
23 | 24 |
24 PathBuffer::PathBuffer() : length_(0) { | 25 PathBuffer::PathBuffer() : length_(0) { |
25 data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT | 26 data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT |
26 } | 27 } |
27 | 28 |
28 char* PathBuffer::AsString() const { | 29 char* PathBuffer::AsString() const { |
29 return StringUtils::WideToUtf8(AsStringW()); | 30 return StringUtilsWin::WideToUtf8(AsStringW()); |
30 } | 31 } |
31 | 32 |
32 wchar_t* PathBuffer::AsStringW() const { | 33 wchar_t* PathBuffer::AsStringW() const { |
33 return reinterpret_cast<wchar_t*>(data_); | 34 return reinterpret_cast<wchar_t*>(data_); |
34 } | 35 } |
35 | 36 |
36 bool PathBuffer::Add(const char* name) { | 37 bool PathBuffer::Add(const char* name) { |
37 const wchar_t* wide_name = StringUtils::Utf8ToWide(name); | 38 const wchar_t* wide_name = StringUtilsWin::Utf8ToWide(name); |
38 bool success = AddW(wide_name); | 39 bool success = AddW(wide_name); |
39 free(const_cast<wchar_t*>(wide_name)); | 40 free(const_cast<wchar_t*>(wide_name)); |
40 return success; | 41 return success; |
41 } | 42 } |
42 | 43 |
43 bool PathBuffer::AddW(const wchar_t* name) { | 44 bool PathBuffer::AddW(const wchar_t* name) { |
44 wchar_t* data = AsStringW(); | 45 wchar_t* data = AsStringW(); |
45 int written = _snwprintf(data + length_, | 46 int written = _snwprintf(data + length_, |
46 MAX_LONG_PATH - length_, | 47 MAX_LONG_PATH - length_, |
47 L"%s", | 48 L"%s", |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 return Directory::UNKNOWN; | 346 return Directory::UNKNOWN; |
346 } | 347 } |
347 } | 348 } |
348 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | 349 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
349 exists = exists && !IsBrokenLink(dir_name); | 350 exists = exists && !IsBrokenLink(dir_name); |
350 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; | 351 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; |
351 } | 352 } |
352 | 353 |
353 | 354 |
354 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 355 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
355 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name); | 356 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name); |
356 Directory::ExistsResult result = ExistsHelper(system_name); | 357 Directory::ExistsResult result = ExistsHelper(system_name); |
357 free(const_cast<wchar_t*>(system_name)); | 358 free(const_cast<wchar_t*>(system_name)); |
358 return result; | 359 return result; |
359 } | 360 } |
360 | 361 |
361 | 362 |
362 char* Directory::Current() { | 363 char* Directory::Current() { |
363 int length = GetCurrentDirectoryW(0, NULL); | 364 int length = GetCurrentDirectoryW(0, NULL); |
364 if (length == 0) return NULL; | 365 if (length == 0) return NULL; |
365 wchar_t* current = new wchar_t[length + 1]; | 366 wchar_t* current = new wchar_t[length + 1]; |
366 GetCurrentDirectoryW(length + 1, current); | 367 GetCurrentDirectoryW(length + 1, current); |
367 char* result = StringUtils::WideToUtf8(current); | 368 char* result = StringUtilsWin::WideToUtf8(current); |
368 delete[] current; | 369 delete[] current; |
369 return result; | 370 return result; |
370 } | 371 } |
371 | 372 |
372 | 373 |
373 bool Directory::SetCurrent(const char* path) { | 374 bool Directory::SetCurrent(const char* path) { |
374 const wchar_t* system_path = StringUtils::Utf8ToWide(path); | 375 const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path); |
375 bool result = SetCurrentDirectoryW(system_path) != 0; | 376 bool result = SetCurrentDirectoryW(system_path) != 0; |
376 free(const_cast<wchar_t*>(system_path)); | 377 free(const_cast<wchar_t*>(system_path)); |
377 return result; | 378 return result; |
378 } | 379 } |
379 | 380 |
380 | 381 |
381 bool Directory::Create(const char* dir_name) { | 382 bool Directory::Create(const char* dir_name) { |
382 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name); | 383 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name); |
383 int create_status = CreateDirectoryW(system_name, NULL); | 384 int create_status = CreateDirectoryW(system_name, NULL); |
384 // If the directory already existed, treat it as a success. | 385 // If the directory already existed, treat it as a success. |
385 if (create_status == 0 && | 386 if (create_status == 0 && |
386 GetLastError() == ERROR_ALREADY_EXISTS && | 387 GetLastError() == ERROR_ALREADY_EXISTS && |
387 ExistsHelper(system_name) == EXISTS) { | 388 ExistsHelper(system_name) == EXISTS) { |
388 free(const_cast<wchar_t*>(system_name)); | 389 free(const_cast<wchar_t*>(system_name)); |
389 return true; | 390 return true; |
390 } | 391 } |
391 free(const_cast<wchar_t*>(system_name)); | 392 free(const_cast<wchar_t*>(system_name)); |
392 return (create_status != 0); | 393 return (create_status != 0); |
393 } | 394 } |
394 | 395 |
395 | 396 |
396 char* Directory::SystemTemp() { | 397 char* Directory::SystemTemp() { |
397 PathBuffer path; | 398 PathBuffer path; |
398 // Remove \ at end. | 399 // Remove \ at end. |
399 path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1); | 400 path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1); |
400 return path.AsString(); | 401 return path.AsString(); |
401 } | 402 } |
402 | 403 |
403 | 404 |
404 char* Directory::CreateTemp(const char* prefix) { | 405 char* Directory::CreateTemp(const char* prefix) { |
405 // Returns a new, unused directory name, adding characters to the | 406 // Returns a new, unused directory name, adding characters to the |
406 // end of prefix. | 407 // end of prefix. |
407 // Creates this directory, with a default security | 408 // Creates this directory, with a default security |
408 // descriptor inherited from its parent directory. | 409 // descriptor inherited from its parent directory. |
409 // The return value must be freed by the caller. | 410 // The return value must be freed by the caller. |
410 PathBuffer path; | 411 PathBuffer path; |
411 const wchar_t* system_prefix = StringUtils::Utf8ToWide(prefix); | 412 const wchar_t* system_prefix = StringUtilsWin::Utf8ToWide(prefix); |
412 path.AddW(system_prefix); | 413 path.AddW(system_prefix); |
413 free(const_cast<wchar_t*>(system_prefix)); | 414 free(const_cast<wchar_t*>(system_prefix)); |
414 | 415 |
415 // Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36. | 416 // Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36. |
416 if (path.length() > MAX_LONG_PATH - 36) { | 417 if (path.length() > MAX_LONG_PATH - 36) { |
417 return NULL; | 418 return NULL; |
418 } | 419 } |
419 | 420 |
420 UUID uuid; | 421 UUID uuid; |
421 RPC_STATUS status = UuidCreateSequential(&uuid); | 422 RPC_STATUS status = UuidCreateSequential(&uuid); |
(...skipping 12 matching lines...) Expand all Loading... |
434 if (!CreateDirectoryW(path.AsStringW(), NULL)) { | 435 if (!CreateDirectoryW(path.AsStringW(), NULL)) { |
435 return NULL; | 436 return NULL; |
436 } | 437 } |
437 char* result = path.AsString(); | 438 char* result = path.AsString(); |
438 return result; | 439 return result; |
439 } | 440 } |
440 | 441 |
441 | 442 |
442 bool Directory::Delete(const char* dir_name, bool recursive) { | 443 bool Directory::Delete(const char* dir_name, bool recursive) { |
443 bool result = false; | 444 bool result = false; |
444 const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name); | 445 const wchar_t* system_dir_name = StringUtilsWin::Utf8ToWide(dir_name); |
445 if (!recursive) { | 446 if (!recursive) { |
446 if (File::GetType(dir_name, true) == File::kIsDirectory) { | 447 if (File::GetType(dir_name, true) == File::kIsDirectory) { |
447 result = (RemoveDirectoryW(system_dir_name) != 0); | 448 result = (RemoveDirectoryW(system_dir_name) != 0); |
448 } else { | 449 } else { |
449 SetLastError(ERROR_FILE_NOT_FOUND); | 450 SetLastError(ERROR_FILE_NOT_FOUND); |
450 } | 451 } |
451 } else { | 452 } else { |
452 PathBuffer path; | 453 PathBuffer path; |
453 if (path.AddW(system_dir_name)) { | 454 if (path.AddW(system_dir_name)) { |
454 result = DeleteRecursively(&path); | 455 result = DeleteRecursively(&path); |
455 } | 456 } |
456 } | 457 } |
457 free(const_cast<wchar_t*>(system_dir_name)); | 458 free(const_cast<wchar_t*>(system_dir_name)); |
458 return result; | 459 return result; |
459 } | 460 } |
460 | 461 |
461 | 462 |
462 bool Directory::Rename(const char* path, const char* new_path) { | 463 bool Directory::Rename(const char* path, const char* new_path) { |
463 const wchar_t* system_path = StringUtils::Utf8ToWide(path); | 464 const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path); |
464 const wchar_t* system_new_path = StringUtils::Utf8ToWide(new_path); | 465 const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); |
465 ExistsResult exists = ExistsHelper(system_path); | 466 ExistsResult exists = ExistsHelper(system_path); |
466 if (exists != EXISTS) return false; | 467 if (exists != EXISTS) return false; |
467 ExistsResult new_exists = ExistsHelper(system_new_path); | 468 ExistsResult new_exists = ExistsHelper(system_new_path); |
468 // MoveFile does not allow replacing exising directories. Therefore, | 469 // MoveFile does not allow replacing exising directories. Therefore, |
469 // if the new_path is currently a directory we need to delete it | 470 // if the new_path is currently a directory we need to delete it |
470 // first. | 471 // first. |
471 if (new_exists == EXISTS) { | 472 if (new_exists == EXISTS) { |
472 bool success = Delete(new_path, true); | 473 bool success = Delete(new_path, true); |
473 if (!success) return false; | 474 if (!success) return false; |
474 } | 475 } |
475 DWORD flags = MOVEFILE_WRITE_THROUGH; | 476 DWORD flags = MOVEFILE_WRITE_THROUGH; |
476 int move_status = | 477 int move_status = |
477 MoveFileExW(system_path, system_new_path, flags); | 478 MoveFileExW(system_path, system_new_path, flags); |
478 free(const_cast<wchar_t*>(system_path)); | 479 free(const_cast<wchar_t*>(system_path)); |
479 free(const_cast<wchar_t*>(system_new_path)); | 480 free(const_cast<wchar_t*>(system_new_path)); |
480 return (move_status != 0); | 481 return (move_status != 0); |
481 } | 482 } |
482 | 483 |
483 } // namespace bin | 484 } // namespace bin |
484 } // namespace dart | 485 } // namespace dart |
485 | 486 |
486 #endif // defined(TARGET_OS_WINDOWS) | 487 #endif // defined(TARGET_OS_WINDOWS) |
OLD | NEW |