| 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 |