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 |