| 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/file.h" | 8 #include "bin/file.h" |
| 9 | 9 |
| 10 #include <fcntl.h> // NOLINT | 10 #include <fcntl.h> // NOLINT |
| 11 #include <io.h> // NOLINT | 11 #include <io.h> // NOLINT |
| 12 #include <stdio.h> // NOLINT | 12 #include <stdio.h> // NOLINT |
| 13 #include <string.h> // NOLINT | 13 #include <string.h> // NOLINT |
| 14 #include <sys/stat.h> // NOLINT | 14 #include <sys/stat.h> // NOLINT |
| 15 #include <WinIoCtl.h> // NOLINT | 15 #include <WinIoCtl.h> // NOLINT |
| 16 | 16 |
| 17 #include "bin/builtin.h" | 17 #include "bin/builtin.h" |
| 18 #include "bin/log.h" | 18 #include "bin/log.h" |
| 19 #include "bin/utils.h" | 19 #include "bin/utils.h" |
| 20 #include "bin/utils_win.h" | 20 #include "bin/utils_win.h" |
| 21 #include "platform/utils.h" | 21 #include "platform/utils.h" |
| 22 | 22 |
| 23 namespace dart { | 23 namespace dart { |
| 24 namespace bin { | 24 namespace bin { |
| 25 | 25 |
| 26 class FileHandle { | 26 class FileHandle { |
| 27 public: | 27 public: |
| 28 explicit FileHandle(int fd) : fd_(fd) { } | 28 explicit FileHandle(int fd) : fd_(fd) {} |
| 29 ~FileHandle() { } | 29 ~FileHandle() {} |
| 30 int fd() const { return fd_; } | 30 int fd() const { return fd_; } |
| 31 void set_fd(int fd) { fd_ = fd; } | 31 void set_fd(int fd) { fd_ = fd; } |
| 32 | 32 |
| 33 private: | 33 private: |
| 34 int fd_; | 34 int fd_; |
| 35 | 35 |
| 36 DISALLOW_COPY_AND_ASSIGN(FileHandle); | 36 DISALLOW_COPY_AND_ASSIGN(FileHandle); |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 | 39 |
| 40 File::~File() { | 40 File::~File() { |
| 41 if (!IsClosed() && | 41 if (!IsClosed() && handle_->fd() != _fileno(stdout) && |
| 42 handle_->fd() != _fileno(stdout) && handle_->fd() != _fileno(stderr)) { | 42 handle_->fd() != _fileno(stderr)) { |
| 43 Close(); | 43 Close(); |
| 44 } | 44 } |
| 45 delete handle_; | 45 delete handle_; |
| 46 } | 46 } |
| 47 | 47 |
| 48 | 48 |
| 49 void File::Close() { | 49 void File::Close() { |
| 50 ASSERT(handle_->fd() >= 0); | 50 ASSERT(handle_->fd() >= 0); |
| 51 if ((handle_->fd() == _fileno(stdout)) || | 51 if ((handle_->fd() == _fileno(stdout)) || |
| 52 (handle_->fd() == _fileno(stderr))) { | 52 (handle_->fd() == _fileno(stderr))) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 case File::kLockBlockingShared: | 177 case File::kLockBlockingShared: |
| 178 case File::kLockBlockingExclusive: { | 178 case File::kLockBlockingExclusive: { |
| 179 DWORD flags = 0; | 179 DWORD flags = 0; |
| 180 if ((lock == File::kLockShared) || (lock == File::kLockExclusive)) { | 180 if ((lock == File::kLockShared) || (lock == File::kLockExclusive)) { |
| 181 flags |= LOCKFILE_FAIL_IMMEDIATELY; | 181 flags |= LOCKFILE_FAIL_IMMEDIATELY; |
| 182 } | 182 } |
| 183 if ((lock == File::kLockExclusive) || | 183 if ((lock == File::kLockExclusive) || |
| 184 (lock == File::kLockBlockingExclusive)) { | 184 (lock == File::kLockBlockingExclusive)) { |
| 185 flags |= LOCKFILE_EXCLUSIVE_LOCK; | 185 flags |= LOCKFILE_EXCLUSIVE_LOCK; |
| 186 } | 186 } |
| 187 rc = LockFileEx(handle, flags, 0, | 187 rc = LockFileEx(handle, flags, 0, length_low, length_high, &overlapped); |
| 188 length_low, length_high, &overlapped); | |
| 189 break; | 188 break; |
| 190 } | 189 } |
| 191 default: | 190 default: |
| 192 UNREACHABLE(); | 191 UNREACHABLE(); |
| 193 } | 192 } |
| 194 return rc; | 193 return rc; |
| 195 } | 194 } |
| 196 | 195 |
| 197 | 196 |
| 198 int64_t File::Length() { | 197 int64_t File::Length() { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 0666); | 272 int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 0666); |
| 274 if (fd < 0) { | 273 if (fd < 0) { |
| 275 return false; | 274 return false; |
| 276 } | 275 } |
| 277 return (close(fd) == 0); | 276 return (close(fd) == 0); |
| 278 } | 277 } |
| 279 | 278 |
| 280 | 279 |
| 281 // This structure is needed for creating and reading Junctions. | 280 // This structure is needed for creating and reading Junctions. |
| 282 typedef struct _REPARSE_DATA_BUFFER { | 281 typedef struct _REPARSE_DATA_BUFFER { |
| 283 ULONG ReparseTag; | 282 ULONG ReparseTag; |
| 284 USHORT ReparseDataLength; | 283 USHORT ReparseDataLength; |
| 285 USHORT Reserved; | 284 USHORT Reserved; |
| 286 | 285 |
| 287 union { | 286 union { |
| 288 struct { | 287 struct { |
| 289 USHORT SubstituteNameOffset; | 288 USHORT SubstituteNameOffset; |
| 290 USHORT SubstituteNameLength; | 289 USHORT SubstituteNameLength; |
| 291 USHORT PrintNameOffset; | 290 USHORT PrintNameOffset; |
| 292 USHORT PrintNameLength; | 291 USHORT PrintNameLength; |
| 293 ULONG Flags; | 292 ULONG Flags; |
| 294 WCHAR PathBuffer[1]; | 293 WCHAR PathBuffer[1]; |
| 295 } SymbolicLinkReparseBuffer; | 294 } SymbolicLinkReparseBuffer; |
| 296 | 295 |
| 297 struct { | 296 struct { |
| 298 USHORT SubstituteNameOffset; | 297 USHORT SubstituteNameOffset; |
| 299 USHORT SubstituteNameLength; | 298 USHORT SubstituteNameLength; |
| 300 USHORT PrintNameOffset; | 299 USHORT PrintNameOffset; |
| 301 USHORT PrintNameLength; | 300 USHORT PrintNameLength; |
| 302 WCHAR PathBuffer[1]; | 301 WCHAR PathBuffer[1]; |
| 303 } MountPointReparseBuffer; | 302 } MountPointReparseBuffer; |
| 304 | 303 |
| 305 struct { | 304 struct { |
| 306 UCHAR DataBuffer[1]; | 305 UCHAR DataBuffer[1]; |
| 307 } GenericReparseBuffer; | 306 } GenericReparseBuffer; |
| 308 }; | 307 }; |
| 309 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; | 308 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; |
| 310 | 309 |
| 311 | 310 |
| 312 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT; | 311 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT; |
| 313 static const int kMountPointHeaderSize = 4 * sizeof USHORT; | 312 static const int kMountPointHeaderSize = 4 * sizeof USHORT; |
| 314 | 313 |
| 315 | 314 |
| 316 bool File::CreateLink(const char* utf8_name, const char* utf8_target) { | 315 bool File::CreateLink(const char* utf8_name, const char* utf8_target) { |
| 317 Utf8ToWideScope name(utf8_name); | 316 Utf8ToWideScope name(utf8_name); |
| 318 int create_status = CreateDirectoryW(name.wide(), NULL); | 317 int create_status = CreateDirectoryW(name.wide(), NULL); |
| 319 // If the directory already existed, treat it as a success. | 318 // If the directory already existed, treat it as a success. |
| 320 if ((create_status == 0) && | 319 if ((create_status == 0) && |
| 321 ((GetLastError() != ERROR_ALREADY_EXISTS) || | 320 ((GetLastError() != ERROR_ALREADY_EXISTS) || |
| 322 ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { | 321 ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { |
| 323 return false; | 322 return false; |
| 324 } | 323 } |
| 325 | 324 |
| 326 HANDLE dir_handle = CreateFileW( | 325 HANDLE dir_handle = CreateFileW( |
| 327 name.wide(), | 326 name.wide(), GENERIC_READ | GENERIC_WRITE, |
| 328 GENERIC_READ | GENERIC_WRITE, | 327 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
| 329 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 328 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
| 330 NULL, | |
| 331 OPEN_EXISTING, | |
| 332 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, | |
| 333 NULL); | 329 NULL); |
| 334 if (dir_handle == INVALID_HANDLE_VALUE) { | 330 if (dir_handle == INVALID_HANDLE_VALUE) { |
| 335 return false; | 331 return false; |
| 336 } | 332 } |
| 337 | 333 |
| 338 Utf8ToWideScope target(utf8_target); | 334 Utf8ToWideScope target(utf8_target); |
| 339 int target_len = wcslen(target.wide()); | 335 int target_len = wcslen(target.wide()); |
| 340 if (target_len > MAX_PATH - 1) { | 336 if (target_len > MAX_PATH - 1) { |
| 341 CloseHandle(dir_handle); | 337 CloseHandle(dir_handle); |
| 342 return false; | 338 return false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 356 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength = | 352 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength = |
| 357 target_len * sizeof WCHAR; | 353 target_len * sizeof WCHAR; |
| 358 reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset = | 354 reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset = |
| 359 (target_len + 1) * sizeof WCHAR; | 355 (target_len + 1) * sizeof WCHAR; |
| 360 reparse_data_buffer->MountPointReparseBuffer.PrintNameLength = | 356 reparse_data_buffer->MountPointReparseBuffer.PrintNameLength = |
| 361 target_len * sizeof WCHAR; | 357 target_len * sizeof WCHAR; |
| 362 reparse_data_buffer->ReparseDataLength = | 358 reparse_data_buffer->ReparseDataLength = |
| 363 (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize; | 359 (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize; |
| 364 DWORD dummy_received_bytes; | 360 DWORD dummy_received_bytes; |
| 365 int result = DeviceIoControl( | 361 int result = DeviceIoControl( |
| 366 dir_handle, | 362 dir_handle, FSCTL_SET_REPARSE_POINT, reparse_data_buffer, |
| 367 FSCTL_SET_REPARSE_POINT, | 363 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, NULL, 0, |
| 368 reparse_data_buffer, | 364 &dummy_received_bytes, NULL); |
| 369 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, | |
| 370 NULL, | |
| 371 0, | |
| 372 &dummy_received_bytes, | |
| 373 NULL); | |
| 374 free(reparse_data_buffer); | 365 free(reparse_data_buffer); |
| 375 if (CloseHandle(dir_handle) == 0) { | 366 if (CloseHandle(dir_handle) == 0) { |
| 376 return false; | 367 return false; |
| 377 } | 368 } |
| 378 return (result != 0); | 369 return (result != 0); |
| 379 } | 370 } |
| 380 | 371 |
| 381 | 372 |
| 382 bool File::Delete(const char* name) { | 373 bool File::Delete(const char* name) { |
| 383 Utf8ToWideScope system_name(name); | 374 Utf8ToWideScope system_name(name); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 } | 422 } |
| 432 return false; | 423 return false; |
| 433 } | 424 } |
| 434 | 425 |
| 435 | 426 |
| 436 bool File::Copy(const char* old_path, const char* new_path) { | 427 bool File::Copy(const char* old_path, const char* new_path) { |
| 437 File::Type type = GetType(old_path, false); | 428 File::Type type = GetType(old_path, false); |
| 438 if (type == kIsFile) { | 429 if (type == kIsFile) { |
| 439 Utf8ToWideScope system_old_path(old_path); | 430 Utf8ToWideScope system_old_path(old_path); |
| 440 Utf8ToWideScope system_new_path(new_path); | 431 Utf8ToWideScope system_new_path(new_path); |
| 441 bool success = CopyFileExW(system_old_path.wide(), | 432 bool success = CopyFileExW(system_old_path.wide(), system_new_path.wide(), |
| 442 system_new_path.wide(), | 433 NULL, NULL, NULL, 0) != 0; |
| 443 NULL, | |
| 444 NULL, | |
| 445 NULL, | |
| 446 0) != 0; | |
| 447 return success; | 434 return success; |
| 448 } else { | 435 } else { |
| 449 SetLastError(ERROR_FILE_NOT_FOUND); | 436 SetLastError(ERROR_FILE_NOT_FOUND); |
| 450 } | 437 } |
| 451 return false; | 438 return false; |
| 452 } | 439 } |
| 453 | 440 |
| 454 | 441 |
| 455 int64_t File::LengthFromPath(const char* name) { | 442 int64_t File::LengthFromPath(const char* name) { |
| 456 struct __stat64 st; | 443 struct __stat64 st; |
| 457 Utf8ToWideScope system_name(name); | 444 Utf8ToWideScope system_name(name); |
| 458 int stat_status = _wstat64(system_name.wide(), &st); | 445 int stat_status = _wstat64(system_name.wide(), &st); |
| 459 if (stat_status == 0) { | 446 if (stat_status == 0) { |
| 460 return st.st_size; | 447 return st.st_size; |
| 461 } | 448 } |
| 462 return -1; | 449 return -1; |
| 463 } | 450 } |
| 464 | 451 |
| 465 | 452 |
| 466 const char* File::LinkTarget(const char* pathname) { | 453 const char* File::LinkTarget(const char* pathname) { |
| 467 const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname); | 454 const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname); |
| 468 HANDLE dir_handle = CreateFileW( | 455 HANDLE dir_handle = CreateFileW( |
| 469 name, | 456 name, GENERIC_READ, |
| 470 GENERIC_READ, | 457 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
| 471 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 458 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
| 472 NULL, | |
| 473 OPEN_EXISTING, | |
| 474 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, | |
| 475 NULL); | 459 NULL); |
| 476 if (dir_handle == INVALID_HANDLE_VALUE) { | 460 if (dir_handle == INVALID_HANDLE_VALUE) { |
| 477 return NULL; | 461 return NULL; |
| 478 } | 462 } |
| 479 | 463 |
| 480 int buffer_size = | 464 int buffer_size = |
| 481 sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR; | 465 sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR; |
| 482 REPARSE_DATA_BUFFER* buffer = reinterpret_cast<REPARSE_DATA_BUFFER*>( | 466 REPARSE_DATA_BUFFER* buffer = |
| 483 Dart_ScopeAllocate(buffer_size)); | 467 reinterpret_cast<REPARSE_DATA_BUFFER*>(Dart_ScopeAllocate(buffer_size)); |
| 484 DWORD received_bytes; // Value is not used. | 468 DWORD received_bytes; // Value is not used. |
| 485 int result = DeviceIoControl( | 469 int result = DeviceIoControl(dir_handle, FSCTL_GET_REPARSE_POINT, NULL, 0, |
| 486 dir_handle, | 470 buffer, buffer_size, &received_bytes, NULL); |
| 487 FSCTL_GET_REPARSE_POINT, | |
| 488 NULL, | |
| 489 0, | |
| 490 buffer, | |
| 491 buffer_size, | |
| 492 &received_bytes, | |
| 493 NULL); | |
| 494 if (result == 0) { | 471 if (result == 0) { |
| 495 DWORD error = GetLastError(); | 472 DWORD error = GetLastError(); |
| 496 CloseHandle(dir_handle); | 473 CloseHandle(dir_handle); |
| 497 SetLastError(error); | 474 SetLastError(error); |
| 498 return NULL; | 475 return NULL; |
| 499 } | 476 } |
| 500 if (CloseHandle(dir_handle) == 0) { | 477 if (CloseHandle(dir_handle) == 0) { |
| 501 return NULL; | 478 return NULL; |
| 502 } | 479 } |
| 503 | 480 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 518 } | 495 } |
| 519 | 496 |
| 520 target_offset /= sizeof(wchar_t); // Offset and length are in bytes. | 497 target_offset /= sizeof(wchar_t); // Offset and length are in bytes. |
| 521 target_length /= sizeof(wchar_t); | 498 target_length /= sizeof(wchar_t); |
| 522 target += target_offset; | 499 target += target_offset; |
| 523 // Remove "\??\" from beginning of target. | 500 // Remove "\??\" from beginning of target. |
| 524 if ((target_length > 4) && (wcsncmp(L"\\??\\", target, 4) == 0)) { | 501 if ((target_length > 4) && (wcsncmp(L"\\??\\", target, 4) == 0)) { |
| 525 target += 4; | 502 target += 4; |
| 526 target_length -= 4; | 503 target_length -= 4; |
| 527 } | 504 } |
| 528 int utf8_length = WideCharToMultiByte(CP_UTF8, | 505 int utf8_length = WideCharToMultiByte(CP_UTF8, 0, target, target_length, NULL, |
| 529 0, | 506 0, NULL, NULL); |
| 530 target, | |
| 531 target_length, | |
| 532 NULL, | |
| 533 0, | |
| 534 NULL, | |
| 535 NULL); | |
| 536 char* utf8_target = DartUtils::ScopedCString(utf8_length + 1); | 507 char* utf8_target = DartUtils::ScopedCString(utf8_length + 1); |
| 537 if (0 == WideCharToMultiByte(CP_UTF8, | 508 if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, utf8_target, |
| 538 0, | 509 utf8_length, NULL, NULL)) { |
| 539 target, | |
| 540 target_length, | |
| 541 utf8_target, | |
| 542 utf8_length, | |
| 543 NULL, | |
| 544 NULL)) { | |
| 545 return NULL; | 510 return NULL; |
| 546 } | 511 } |
| 547 utf8_target[utf8_length] = '\0'; | 512 utf8_target[utf8_length] = '\0'; |
| 548 return utf8_target; | 513 return utf8_target; |
| 549 } | 514 } |
| 550 | 515 |
| 551 | 516 |
| 552 void File::Stat(const char* name, int64_t* data) { | 517 void File::Stat(const char* name, int64_t* data) { |
| 553 File::Type type = GetType(name, false); | 518 File::Type type = GetType(name, false); |
| 554 data[kType] = type; | 519 data[kType] = type; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 578 } | 543 } |
| 579 return -1; | 544 return -1; |
| 580 } | 545 } |
| 581 | 546 |
| 582 | 547 |
| 583 bool File::IsAbsolutePath(const char* pathname) { | 548 bool File::IsAbsolutePath(const char* pathname) { |
| 584 // Should we consider network paths? | 549 // Should we consider network paths? |
| 585 if (pathname == NULL) { | 550 if (pathname == NULL) { |
| 586 return false; | 551 return false; |
| 587 } | 552 } |
| 588 return ((strlen(pathname) > 2) && | 553 return ((strlen(pathname) > 2) && (pathname[1] == ':') && |
| 589 (pathname[1] == ':') && | 554 ((pathname[2] == '\\') || (pathname[2] == '/'))); |
| 590 ((pathname[2] == '\\') || (pathname[2] == '/'))); | |
| 591 } | 555 } |
| 592 | 556 |
| 593 | 557 |
| 594 const char* File::GetCanonicalPath(const char* pathname) { | 558 const char* File::GetCanonicalPath(const char* pathname) { |
| 595 Utf8ToWideScope system_name(pathname); | 559 Utf8ToWideScope system_name(pathname); |
| 596 HANDLE file_handle = CreateFileW( | 560 HANDLE file_handle = |
| 597 system_name.wide(), | 561 CreateFileW(system_name.wide(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, |
| 598 0, | 562 FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 599 FILE_SHARE_READ, | |
| 600 NULL, | |
| 601 OPEN_EXISTING, | |
| 602 FILE_FLAG_BACKUP_SEMANTICS, | |
| 603 NULL); | |
| 604 if (file_handle == INVALID_HANDLE_VALUE) { | 563 if (file_handle == INVALID_HANDLE_VALUE) { |
| 605 return NULL; | 564 return NULL; |
| 606 } | 565 } |
| 607 wchar_t dummy_buffer[1]; | 566 wchar_t dummy_buffer[1]; |
| 608 int required_size = GetFinalPathNameByHandle(file_handle, | 567 int required_size = |
| 609 dummy_buffer, | 568 GetFinalPathNameByHandle(file_handle, dummy_buffer, 0, VOLUME_NAME_DOS); |
| 610 0, | |
| 611 VOLUME_NAME_DOS); | |
| 612 if (required_size == 0) { | 569 if (required_size == 0) { |
| 613 DWORD error = GetLastError(); | 570 DWORD error = GetLastError(); |
| 614 CloseHandle(file_handle); | 571 CloseHandle(file_handle); |
| 615 SetLastError(error); | 572 SetLastError(error); |
| 616 return NULL; | 573 return NULL; |
| 617 } | 574 } |
| 618 wchar_t* path; | 575 wchar_t* path; |
| 619 path = reinterpret_cast<wchar_t*>( | 576 path = reinterpret_cast<wchar_t*>( |
| 620 Dart_ScopeAllocate(required_size * sizeof(*path))); | 577 Dart_ScopeAllocate(required_size * sizeof(*path))); |
| 621 int result_size = GetFinalPathNameByHandle(file_handle, | 578 int result_size = GetFinalPathNameByHandle(file_handle, path, required_size, |
| 622 path, | |
| 623 required_size, | |
| 624 VOLUME_NAME_DOS); | 579 VOLUME_NAME_DOS); |
| 625 ASSERT(result_size <= required_size - 1); | 580 ASSERT(result_size <= required_size - 1); |
| 626 // Remove leading \\?\ if possible, unless input used it. | 581 // Remove leading \\?\ if possible, unless input used it. |
| 627 char* result; | 582 char* result; |
| 628 if ((result_size < MAX_PATH - 1 + 4) && | 583 if ((result_size < MAX_PATH - 1 + 4) && (result_size > 4) && |
| 629 (result_size > 4) && | |
| 630 (wcsncmp(path, L"\\\\?\\", 4) == 0) && | 584 (wcsncmp(path, L"\\\\?\\", 4) == 0) && |
| 631 (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) { | 585 (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) { |
| 632 result = StringUtilsWin::WideToUtf8(path + 4); | 586 result = StringUtilsWin::WideToUtf8(path + 4); |
| 633 } else { | 587 } else { |
| 634 result = StringUtilsWin::WideToUtf8(path); | 588 result = StringUtilsWin::WideToUtf8(path); |
| 635 } | 589 } |
| 636 CloseHandle(file_handle); | 590 CloseHandle(file_handle); |
| 637 return result; | 591 return result; |
| 638 } | 592 } |
| 639 | 593 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 659 | 613 |
| 660 File::Type File::GetType(const char* pathname, bool follow_links) { | 614 File::Type File::GetType(const char* pathname, bool follow_links) { |
| 661 // Convert to wchar_t string. | 615 // Convert to wchar_t string. |
| 662 Utf8ToWideScope name(pathname); | 616 Utf8ToWideScope name(pathname); |
| 663 DWORD attributes = GetFileAttributesW(name.wide()); | 617 DWORD attributes = GetFileAttributesW(name.wide()); |
| 664 File::Type result = kIsFile; | 618 File::Type result = kIsFile; |
| 665 if (attributes == INVALID_FILE_ATTRIBUTES) { | 619 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 666 result = kDoesNotExist; | 620 result = kDoesNotExist; |
| 667 } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 621 } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 668 if (follow_links) { | 622 if (follow_links) { |
| 669 HANDLE dir_handle = CreateFileW( | 623 HANDLE dir_handle = |
| 670 name.wide(), | 624 CreateFileW(name.wide(), 0, |
| 671 0, | 625 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 672 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 626 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 673 NULL, | |
| 674 OPEN_EXISTING, | |
| 675 FILE_FLAG_BACKUP_SEMANTICS, | |
| 676 NULL); | |
| 677 if (dir_handle == INVALID_HANDLE_VALUE) { | 627 if (dir_handle == INVALID_HANDLE_VALUE) { |
| 678 result = File::kIsLink; | 628 result = File::kIsLink; |
| 679 } else { | 629 } else { |
| 680 CloseHandle(dir_handle); | 630 CloseHandle(dir_handle); |
| 681 result = File::kIsDirectory; | 631 result = File::kIsDirectory; |
| 682 } | 632 } |
| 683 } else { | 633 } else { |
| 684 result = kIsLink; | 634 result = kIsLink; |
| 685 } | 635 } |
| 686 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 636 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 687 result = kIsDirectory; | 637 result = kIsDirectory; |
| 688 } | 638 } |
| 689 return result; | 639 return result; |
| 690 } | 640 } |
| 691 | 641 |
| 692 | 642 |
| 693 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 643 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
| 694 BY_HANDLE_FILE_INFORMATION file_info[2]; | 644 BY_HANDLE_FILE_INFORMATION file_info[2]; |
| 695 const char* file_names[2] = { file_1, file_2 }; | 645 const char* file_names[2] = {file_1, file_2}; |
| 696 for (int i = 0; i < 2; ++i) { | 646 for (int i = 0; i < 2; ++i) { |
| 697 Utf8ToWideScope wide_name(file_names[i]); | 647 Utf8ToWideScope wide_name(file_names[i]); |
| 698 HANDLE file_handle = CreateFileW( | 648 HANDLE file_handle = CreateFileW( |
| 699 wide_name.wide(), | 649 wide_name.wide(), 0, |
| 700 0, | 650 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
| 701 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | |
| 702 NULL, | |
| 703 OPEN_EXISTING, | 651 OPEN_EXISTING, |
| 704 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, | 652 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 705 NULL); | |
| 706 if (file_handle == INVALID_HANDLE_VALUE) { | 653 if (file_handle == INVALID_HANDLE_VALUE) { |
| 707 return File::kError; | 654 return File::kError; |
| 708 } | 655 } |
| 709 int result = GetFileInformationByHandle(file_handle, &file_info[i]); | 656 int result = GetFileInformationByHandle(file_handle, &file_info[i]); |
| 710 if (result == 0) { | 657 if (result == 0) { |
| 711 DWORD error = GetLastError(); | 658 DWORD error = GetLastError(); |
| 712 CloseHandle(file_handle); | 659 CloseHandle(file_handle); |
| 713 SetLastError(error); | 660 SetLastError(error); |
| 714 return File::kError; | 661 return File::kError; |
| 715 } | 662 } |
| 716 if (CloseHandle(file_handle) == 0) { | 663 if (CloseHandle(file_handle) == 0) { |
| 717 return File::kError; | 664 return File::kError; |
| 718 } | 665 } |
| 719 } | 666 } |
| 720 if ((file_info[0].dwVolumeSerialNumber == | 667 if ((file_info[0].dwVolumeSerialNumber == |
| 721 file_info[1].dwVolumeSerialNumber) && | 668 file_info[1].dwVolumeSerialNumber) && |
| 722 (file_info[0].nFileIndexHigh == file_info[1].nFileIndexHigh) && | 669 (file_info[0].nFileIndexHigh == file_info[1].nFileIndexHigh) && |
| 723 (file_info[0].nFileIndexLow == file_info[1].nFileIndexLow)) { | 670 (file_info[0].nFileIndexLow == file_info[1].nFileIndexLow)) { |
| 724 return kIdentical; | 671 return kIdentical; |
| 725 } else { | 672 } else { |
| 726 return kDifferent; | 673 return kDifferent; |
| 727 } | 674 } |
| 728 } | 675 } |
| 729 | 676 |
| 730 } // namespace bin | 677 } // namespace bin |
| 731 } // namespace dart | 678 } // namespace dart |
| 732 | 679 |
| 733 #endif // defined(TARGET_OS_WINDOWS) | 680 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |