| 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 |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { | 226 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { |
| 227 int64_t position = _lseeki64(fd, 0, SEEK_END); | 227 int64_t position = _lseeki64(fd, 0, SEEK_END); |
| 228 if (position < 0) { | 228 if (position < 0) { |
| 229 return NULL; | 229 return NULL; |
| 230 } | 230 } |
| 231 } | 231 } |
| 232 return new File(new FileHandle(fd)); | 232 return new File(new FileHandle(fd)); |
| 233 } | 233 } |
| 234 | 234 |
| 235 | 235 |
| 236 File* File::ScopedOpen(const char* name, FileOpenMode mode) { | |
| 237 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | |
| 238 return FileOpenW(system_name, mode); | |
| 239 } | |
| 240 | |
| 241 | |
| 242 File* File::Open(const char* path, FileOpenMode mode) { | 236 File* File::Open(const char* path, FileOpenMode mode) { |
| 243 int path_len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); | 237 Utf8ToWideScope system_name(path); |
| 244 wchar_t* system_name = new wchar_t[path_len]; | 238 File* file = FileOpenW(system_name.wide(), mode); |
| 245 if (system_name == NULL) { | |
| 246 return NULL; | |
| 247 } | |
| 248 MultiByteToWideChar(CP_UTF8, 0, path, -1, system_name, path_len); | |
| 249 File* file = FileOpenW(system_name, mode); | |
| 250 delete[] system_name; | |
| 251 return file; | 239 return file; |
| 252 } | 240 } |
| 253 | 241 |
| 254 | 242 |
| 255 File* File::OpenStdio(int fd) { | 243 File* File::OpenStdio(int fd) { |
| 256 switch (fd) { | 244 switch (fd) { |
| 257 case 1: | 245 case 1: |
| 258 fd = _fileno(stdout); | 246 fd = _fileno(stdout); |
| 259 break; | 247 break; |
| 260 case 2: | 248 case 2: |
| 261 fd = _fileno(stderr); | 249 fd = _fileno(stderr); |
| 262 break; | 250 break; |
| 263 default: | 251 default: |
| 264 UNREACHABLE(); | 252 UNREACHABLE(); |
| 265 } | 253 } |
| 266 _setmode(fd, _O_BINARY); | 254 _setmode(fd, _O_BINARY); |
| 267 return new File(new FileHandle(fd)); | 255 return new File(new FileHandle(fd)); |
| 268 } | 256 } |
| 269 | 257 |
| 270 | 258 |
| 271 bool File::Exists(const char* name) { | 259 bool File::Exists(const char* name) { |
| 272 struct __stat64 st; | 260 struct __stat64 st; |
| 273 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 261 Utf8ToWideScope system_name(name); |
| 274 bool stat_status = _wstat64(system_name, &st); | 262 bool stat_status = _wstat64(system_name.wide(), &st); |
| 275 if (stat_status == 0) { | 263 if (stat_status == 0) { |
| 276 return ((st.st_mode & S_IFMT) == S_IFREG); | 264 return ((st.st_mode & S_IFMT) == S_IFREG); |
| 277 } else { | 265 } else { |
| 278 return false; | 266 return false; |
| 279 } | 267 } |
| 280 } | 268 } |
| 281 | 269 |
| 282 | 270 |
| 283 bool File::Create(const char* name) { | 271 bool File::Create(const char* name) { |
| 284 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 272 Utf8ToWideScope system_name(name); |
| 285 int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666); | 273 int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 0666); |
| 286 if (fd < 0) { | 274 if (fd < 0) { |
| 287 return false; | 275 return false; |
| 288 } | 276 } |
| 289 return (close(fd) == 0); | 277 return (close(fd) == 0); |
| 290 } | 278 } |
| 291 | 279 |
| 292 | 280 |
| 293 // This structure is needed for creating and reading Junctions. | 281 // This structure is needed for creating and reading Junctions. |
| 294 typedef struct _REPARSE_DATA_BUFFER { | 282 typedef struct _REPARSE_DATA_BUFFER { |
| 295 ULONG ReparseTag; | 283 ULONG ReparseTag; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 319 } GenericReparseBuffer; | 307 } GenericReparseBuffer; |
| 320 }; | 308 }; |
| 321 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; | 309 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; |
| 322 | 310 |
| 323 | 311 |
| 324 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT; | 312 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT; |
| 325 static const int kMountPointHeaderSize = 4 * sizeof USHORT; | 313 static const int kMountPointHeaderSize = 4 * sizeof USHORT; |
| 326 | 314 |
| 327 | 315 |
| 328 bool File::CreateLink(const char* utf8_name, const char* utf8_target) { | 316 bool File::CreateLink(const char* utf8_name, const char* utf8_target) { |
| 329 const wchar_t* name = StringUtilsWin::Utf8ToWide(utf8_name); | 317 Utf8ToWideScope name(utf8_name); |
| 330 int create_status = CreateDirectoryW(name, NULL); | 318 int create_status = CreateDirectoryW(name.wide(), NULL); |
| 331 // If the directory already existed, treat it as a success. | 319 // If the directory already existed, treat it as a success. |
| 332 if ((create_status == 0) && | 320 if ((create_status == 0) && |
| 333 ((GetLastError() != ERROR_ALREADY_EXISTS) || | 321 ((GetLastError() != ERROR_ALREADY_EXISTS) || |
| 334 ((GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { | 322 ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { |
| 335 return false; | 323 return false; |
| 336 } | 324 } |
| 337 | 325 |
| 338 HANDLE dir_handle = CreateFileW( | 326 HANDLE dir_handle = CreateFileW( |
| 339 name, | 327 name.wide(), |
| 340 GENERIC_READ | GENERIC_WRITE, | 328 GENERIC_READ | GENERIC_WRITE, |
| 341 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 329 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 342 NULL, | 330 NULL, |
| 343 OPEN_EXISTING, | 331 OPEN_EXISTING, |
| 344 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, | 332 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
| 345 NULL); | 333 NULL); |
| 346 if (dir_handle == INVALID_HANDLE_VALUE) { | 334 if (dir_handle == INVALID_HANDLE_VALUE) { |
| 347 return false; | 335 return false; |
| 348 } | 336 } |
| 349 | 337 |
| 350 const wchar_t* target = StringUtilsWin::Utf8ToWide(utf8_target); | 338 Utf8ToWideScope target(utf8_target); |
| 351 int target_len = wcslen(target); | 339 int target_len = wcslen(target.wide()); |
| 352 if (target_len > MAX_PATH - 1) { | 340 if (target_len > MAX_PATH - 1) { |
| 353 CloseHandle(dir_handle); | 341 CloseHandle(dir_handle); |
| 354 return false; | 342 return false; |
| 355 } | 343 } |
| 356 | 344 |
| 357 int reparse_data_buffer_size = | 345 int reparse_data_buffer_size = |
| 358 sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR; | 346 sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR; |
| 359 REPARSE_DATA_BUFFER* reparse_data_buffer = | 347 REPARSE_DATA_BUFFER* reparse_data_buffer = |
| 360 reinterpret_cast<REPARSE_DATA_BUFFER*>(Dart_ScopeAllocate( | 348 reinterpret_cast<REPARSE_DATA_BUFFER*>(malloc(reparse_data_buffer_size)); |
| 361 reparse_data_buffer_size)); | |
| 362 reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; | 349 reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; |
| 363 wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, target); | 350 wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, |
| 351 target.wide()); |
| 364 wcscpy( | 352 wcscpy( |
| 365 reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1, | 353 reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1, |
| 366 target); | 354 target.wide()); |
| 367 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0; | 355 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0; |
| 368 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength = | 356 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength = |
| 369 target_len * sizeof WCHAR; | 357 target_len * sizeof WCHAR; |
| 370 reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset = | 358 reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset = |
| 371 (target_len + 1) * sizeof WCHAR; | 359 (target_len + 1) * sizeof WCHAR; |
| 372 reparse_data_buffer->MountPointReparseBuffer.PrintNameLength = | 360 reparse_data_buffer->MountPointReparseBuffer.PrintNameLength = |
| 373 target_len * sizeof WCHAR; | 361 target_len * sizeof WCHAR; |
| 374 reparse_data_buffer->ReparseDataLength = | 362 reparse_data_buffer->ReparseDataLength = |
| 375 (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize; | 363 (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize; |
| 376 DWORD dummy_received_bytes; | 364 DWORD dummy_received_bytes; |
| 377 int result = DeviceIoControl( | 365 int result = DeviceIoControl( |
| 378 dir_handle, | 366 dir_handle, |
| 379 FSCTL_SET_REPARSE_POINT, | 367 FSCTL_SET_REPARSE_POINT, |
| 380 reparse_data_buffer, | 368 reparse_data_buffer, |
| 381 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, | 369 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, |
| 382 NULL, | 370 NULL, |
| 383 0, | 371 0, |
| 384 &dummy_received_bytes, | 372 &dummy_received_bytes, |
| 385 NULL); | 373 NULL); |
| 374 free(reparse_data_buffer); |
| 386 if (CloseHandle(dir_handle) == 0) { | 375 if (CloseHandle(dir_handle) == 0) { |
| 387 return false; | 376 return false; |
| 388 } | 377 } |
| 389 return (result != 0); | 378 return (result != 0); |
| 390 } | 379 } |
| 391 | 380 |
| 392 | 381 |
| 393 bool File::Delete(const char* name) { | 382 bool File::Delete(const char* name) { |
| 394 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 383 Utf8ToWideScope system_name(name); |
| 395 int status = _wremove(system_name); | 384 int status = _wremove(system_name.wide()); |
| 396 return status != -1; | 385 return status != -1; |
| 397 } | 386 } |
| 398 | 387 |
| 399 | 388 |
| 400 bool File::DeleteLink(const char* name) { | 389 bool File::DeleteLink(const char* name) { |
| 401 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 390 Utf8ToWideScope system_name(name); |
| 402 bool result = false; | 391 bool result = false; |
| 403 DWORD attributes = GetFileAttributesW(system_name); | 392 DWORD attributes = GetFileAttributesW(system_name.wide()); |
| 404 if ((attributes != INVALID_FILE_ATTRIBUTES) && | 393 if ((attributes != INVALID_FILE_ATTRIBUTES) && |
| 405 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 394 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 406 // It's a junction(link), delete it. | 395 // It's a junction(link), delete it. |
| 407 result = (RemoveDirectoryW(system_name) != 0); | 396 result = (RemoveDirectoryW(system_name.wide()) != 0); |
| 408 } else { | 397 } else { |
| 409 SetLastError(ERROR_NOT_A_REPARSE_POINT); | 398 SetLastError(ERROR_NOT_A_REPARSE_POINT); |
| 410 } | 399 } |
| 411 return result; | 400 return result; |
| 412 } | 401 } |
| 413 | 402 |
| 414 | 403 |
| 415 bool File::Rename(const char* old_path, const char* new_path) { | 404 bool File::Rename(const char* old_path, const char* new_path) { |
| 416 File::Type type = GetType(old_path, false); | 405 File::Type type = GetType(old_path, false); |
| 417 if (type == kIsFile) { | 406 if (type == kIsFile) { |
| 418 const wchar_t* system_old_path = StringUtilsWin::Utf8ToWide(old_path); | 407 Utf8ToWideScope system_old_path(old_path); |
| 419 const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); | 408 Utf8ToWideScope system_new_path(new_path); |
| 420 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; | 409 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; |
| 421 int move_status = | 410 int move_status = |
| 422 MoveFileExW(system_old_path, system_new_path, flags); | 411 MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); |
| 423 return (move_status != 0); | 412 return (move_status != 0); |
| 424 } else { | 413 } else { |
| 425 SetLastError(ERROR_FILE_NOT_FOUND); | 414 SetLastError(ERROR_FILE_NOT_FOUND); |
| 426 } | 415 } |
| 427 return false; | 416 return false; |
| 428 } | 417 } |
| 429 | 418 |
| 430 | 419 |
| 431 bool File::RenameLink(const char* old_path, const char* new_path) { | 420 bool File::RenameLink(const char* old_path, const char* new_path) { |
| 432 File::Type type = GetType(old_path, false); | 421 File::Type type = GetType(old_path, false); |
| 433 if (type == kIsLink) { | 422 if (type == kIsLink) { |
| 434 const wchar_t* system_old_path = StringUtilsWin::Utf8ToWide(old_path); | 423 Utf8ToWideScope system_old_path(old_path); |
| 435 const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); | 424 Utf8ToWideScope system_new_path(new_path); |
| 436 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; | 425 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; |
| 437 int move_status = | 426 int move_status = |
| 438 MoveFileExW(system_old_path, system_new_path, flags); | 427 MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); |
| 439 return (move_status != 0); | 428 return (move_status != 0); |
| 440 } else { | 429 } else { |
| 441 SetLastError(ERROR_FILE_NOT_FOUND); | 430 SetLastError(ERROR_FILE_NOT_FOUND); |
| 442 } | 431 } |
| 443 return false; | 432 return false; |
| 444 } | 433 } |
| 445 | 434 |
| 446 | 435 |
| 447 bool File::Copy(const char* old_path, const char* new_path) { | 436 bool File::Copy(const char* old_path, const char* new_path) { |
| 448 File::Type type = GetType(old_path, false); | 437 File::Type type = GetType(old_path, false); |
| 449 if (type == kIsFile) { | 438 if (type == kIsFile) { |
| 450 const wchar_t* system_old_path = StringUtilsWin::Utf8ToWide(old_path); | 439 Utf8ToWideScope system_old_path(old_path); |
| 451 const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path); | 440 Utf8ToWideScope system_new_path(new_path); |
| 452 bool success = CopyFileExW(system_old_path, | 441 bool success = CopyFileExW(system_old_path.wide(), |
| 453 system_new_path, | 442 system_new_path.wide(), |
| 454 NULL, | 443 NULL, |
| 455 NULL, | 444 NULL, |
| 456 NULL, | 445 NULL, |
| 457 0) != 0; | 446 0) != 0; |
| 458 return success; | 447 return success; |
| 459 } else { | 448 } else { |
| 460 SetLastError(ERROR_FILE_NOT_FOUND); | 449 SetLastError(ERROR_FILE_NOT_FOUND); |
| 461 } | 450 } |
| 462 return false; | 451 return false; |
| 463 } | 452 } |
| 464 | 453 |
| 465 | 454 |
| 466 int64_t File::LengthFromPath(const char* name) { | 455 int64_t File::LengthFromPath(const char* name) { |
| 467 struct __stat64 st; | 456 struct __stat64 st; |
| 468 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 457 Utf8ToWideScope system_name(name); |
| 469 int stat_status = _wstat64(system_name, &st); | 458 int stat_status = _wstat64(system_name.wide(), &st); |
| 470 if (stat_status == 0) { | 459 if (stat_status == 0) { |
| 471 return st.st_size; | 460 return st.st_size; |
| 472 } | 461 } |
| 473 return -1; | 462 return -1; |
| 474 } | 463 } |
| 475 | 464 |
| 476 | 465 |
| 477 const char* File::LinkTarget(const char* pathname) { | 466 const char* File::LinkTarget(const char* pathname) { |
| 478 const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname); | 467 const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname); |
| 479 HANDLE dir_handle = CreateFileW( | 468 HANDLE dir_handle = CreateFileW( |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 utf8_target[utf8_length] = '\0'; | 547 utf8_target[utf8_length] = '\0'; |
| 559 return utf8_target; | 548 return utf8_target; |
| 560 } | 549 } |
| 561 | 550 |
| 562 | 551 |
| 563 void File::Stat(const char* name, int64_t* data) { | 552 void File::Stat(const char* name, int64_t* data) { |
| 564 File::Type type = GetType(name, false); | 553 File::Type type = GetType(name, false); |
| 565 data[kType] = type; | 554 data[kType] = type; |
| 566 if (type != kDoesNotExist) { | 555 if (type != kDoesNotExist) { |
| 567 struct _stat64 st; | 556 struct _stat64 st; |
| 568 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 557 Utf8ToWideScope system_name(name); |
| 569 int stat_status = _wstat64(system_name, &st); | 558 int stat_status = _wstat64(system_name.wide(), &st); |
| 570 if (stat_status == 0) { | 559 if (stat_status == 0) { |
| 571 data[kCreatedTime] = st.st_ctime * 1000; | 560 data[kCreatedTime] = st.st_ctime * 1000; |
| 572 data[kModifiedTime] = st.st_mtime * 1000; | 561 data[kModifiedTime] = st.st_mtime * 1000; |
| 573 data[kAccessedTime] = st.st_atime * 1000; | 562 data[kAccessedTime] = st.st_atime * 1000; |
| 574 data[kMode] = st.st_mode; | 563 data[kMode] = st.st_mode; |
| 575 data[kSize] = st.st_size; | 564 data[kSize] = st.st_size; |
| 576 } else { | 565 } else { |
| 577 data[kType] = File::kDoesNotExist; | 566 data[kType] = File::kDoesNotExist; |
| 578 } | 567 } |
| 579 } | 568 } |
| 580 } | 569 } |
| 581 | 570 |
| 582 | 571 |
| 583 time_t File::LastModified(const char* name) { | 572 time_t File::LastModified(const char* name) { |
| 584 struct __stat64 st; | 573 struct __stat64 st; |
| 585 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name); | 574 Utf8ToWideScope system_name(name); |
| 586 int stat_status = _wstat64(system_name, &st); | 575 int stat_status = _wstat64(system_name.wide(), &st); |
| 587 if (stat_status == 0) { | 576 if (stat_status == 0) { |
| 588 return st.st_mtime; | 577 return st.st_mtime; |
| 589 } | 578 } |
| 590 return -1; | 579 return -1; |
| 591 } | 580 } |
| 592 | 581 |
| 593 | 582 |
| 594 bool File::IsAbsolutePath(const char* pathname) { | 583 bool File::IsAbsolutePath(const char* pathname) { |
| 595 // Should we consider network paths? | 584 // Should we consider network paths? |
| 596 if (pathname == NULL) { | 585 if (pathname == NULL) { |
| 597 return false; | 586 return false; |
| 598 } | 587 } |
| 599 return ((strlen(pathname) > 2) && | 588 return ((strlen(pathname) > 2) && |
| 600 (pathname[1] == ':') && | 589 (pathname[1] == ':') && |
| 601 ((pathname[2] == '\\') || (pathname[2] == '/'))); | 590 ((pathname[2] == '\\') || (pathname[2] == '/'))); |
| 602 } | 591 } |
| 603 | 592 |
| 604 | 593 |
| 605 const char* File::GetCanonicalPath(const char* pathname) { | 594 const char* File::GetCanonicalPath(const char* pathname) { |
| 606 const wchar_t* system_name = StringUtilsWin::Utf8ToWide(pathname); | 595 Utf8ToWideScope system_name(pathname); |
| 607 HANDLE file_handle = CreateFileW( | 596 HANDLE file_handle = CreateFileW( |
| 608 system_name, | 597 system_name.wide(), |
| 609 0, | 598 0, |
| 610 FILE_SHARE_READ, | 599 FILE_SHARE_READ, |
| 611 NULL, | 600 NULL, |
| 612 OPEN_EXISTING, | 601 OPEN_EXISTING, |
| 613 FILE_FLAG_BACKUP_SEMANTICS, | 602 FILE_FLAG_BACKUP_SEMANTICS, |
| 614 NULL); | 603 NULL); |
| 615 if (file_handle == INVALID_HANDLE_VALUE) { | 604 if (file_handle == INVALID_HANDLE_VALUE) { |
| 616 return NULL; | 605 return NULL; |
| 617 } | 606 } |
| 618 wchar_t dummy_buffer[1]; | 607 wchar_t dummy_buffer[1]; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 632 int result_size = GetFinalPathNameByHandle(file_handle, | 621 int result_size = GetFinalPathNameByHandle(file_handle, |
| 633 path, | 622 path, |
| 634 required_size, | 623 required_size, |
| 635 VOLUME_NAME_DOS); | 624 VOLUME_NAME_DOS); |
| 636 ASSERT(result_size <= required_size - 1); | 625 ASSERT(result_size <= required_size - 1); |
| 637 // Remove leading \\?\ if possible, unless input used it. | 626 // Remove leading \\?\ if possible, unless input used it. |
| 638 char* result; | 627 char* result; |
| 639 if ((result_size < MAX_PATH - 1 + 4) && | 628 if ((result_size < MAX_PATH - 1 + 4) && |
| 640 (result_size > 4) && | 629 (result_size > 4) && |
| 641 (wcsncmp(path, L"\\\\?\\", 4) == 0) && | 630 (wcsncmp(path, L"\\\\?\\", 4) == 0) && |
| 642 (wcsncmp(system_name, L"\\\\?\\", 4) != 0)) { | 631 (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) { |
| 643 result = StringUtilsWin::WideToUtf8(path + 4); | 632 result = StringUtilsWin::WideToUtf8(path + 4); |
| 644 } else { | 633 } else { |
| 645 result = StringUtilsWin::WideToUtf8(path); | 634 result = StringUtilsWin::WideToUtf8(path); |
| 646 } | 635 } |
| 647 CloseHandle(file_handle); | 636 CloseHandle(file_handle); |
| 648 return result; | 637 return result; |
| 649 } | 638 } |
| 650 | 639 |
| 651 | 640 |
| 652 const char* File::PathSeparator() { | 641 const char* File::PathSeparator() { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 663 | 652 |
| 664 File::StdioHandleType File::GetStdioHandleType(int fd) { | 653 File::StdioHandleType File::GetStdioHandleType(int fd) { |
| 665 // Treat all stdio handles as pipes. The Windows event handler and | 654 // Treat all stdio handles as pipes. The Windows event handler and |
| 666 // socket code will handle the different handle types. | 655 // socket code will handle the different handle types. |
| 667 return kPipe; | 656 return kPipe; |
| 668 } | 657 } |
| 669 | 658 |
| 670 | 659 |
| 671 File::Type File::GetType(const char* pathname, bool follow_links) { | 660 File::Type File::GetType(const char* pathname, bool follow_links) { |
| 672 // Convert to wchar_t string. | 661 // Convert to wchar_t string. |
| 673 int name_len = MultiByteToWideChar(CP_UTF8, 0, pathname, -1, NULL, 0); | 662 Utf8ToWideScope name(pathname); |
| 674 wchar_t* name; | 663 DWORD attributes = GetFileAttributesW(name.wide()); |
| 675 name = new wchar_t[name_len]; | |
| 676 MultiByteToWideChar(CP_UTF8, 0, pathname, -1, name, name_len); | |
| 677 | |
| 678 DWORD attributes = GetFileAttributesW(name); | |
| 679 File::Type result = kIsFile; | 664 File::Type result = kIsFile; |
| 680 if (attributes == INVALID_FILE_ATTRIBUTES) { | 665 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 681 result = kDoesNotExist; | 666 result = kDoesNotExist; |
| 682 } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 667 } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 683 if (follow_links) { | 668 if (follow_links) { |
| 684 HANDLE dir_handle = CreateFileW( | 669 HANDLE dir_handle = CreateFileW( |
| 685 name, | 670 name.wide(), |
| 686 0, | 671 0, |
| 687 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 672 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 688 NULL, | 673 NULL, |
| 689 OPEN_EXISTING, | 674 OPEN_EXISTING, |
| 690 FILE_FLAG_BACKUP_SEMANTICS, | 675 FILE_FLAG_BACKUP_SEMANTICS, |
| 691 NULL); | 676 NULL); |
| 692 if (dir_handle == INVALID_HANDLE_VALUE) { | 677 if (dir_handle == INVALID_HANDLE_VALUE) { |
| 693 result = File::kIsLink; | 678 result = File::kIsLink; |
| 694 } else { | 679 } else { |
| 695 CloseHandle(dir_handle); | 680 CloseHandle(dir_handle); |
| 696 result = File::kIsDirectory; | 681 result = File::kIsDirectory; |
| 697 } | 682 } |
| 698 } else { | 683 } else { |
| 699 result = kIsLink; | 684 result = kIsLink; |
| 700 } | 685 } |
| 701 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 686 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 702 result = kIsDirectory; | 687 result = kIsDirectory; |
| 703 } | 688 } |
| 704 delete[] name; | |
| 705 return result; | 689 return result; |
| 706 } | 690 } |
| 707 | 691 |
| 708 | 692 |
| 709 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 693 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
| 710 BY_HANDLE_FILE_INFORMATION file_info[2]; | 694 BY_HANDLE_FILE_INFORMATION file_info[2]; |
| 711 const char* file_names[2] = { file_1, file_2 }; | 695 const char* file_names[2] = { file_1, file_2 }; |
| 712 for (int i = 0; i < 2; ++i) { | 696 for (int i = 0; i < 2; ++i) { |
| 713 const wchar_t* wide_name = StringUtilsWin::Utf8ToWide(file_names[i]); | 697 Utf8ToWideScope wide_name(file_names[i]); |
| 714 HANDLE file_handle = CreateFileW( | 698 HANDLE file_handle = CreateFileW( |
| 715 wide_name, | 699 wide_name.wide(), |
| 716 0, | 700 0, |
| 717 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 701 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 718 NULL, | 702 NULL, |
| 719 OPEN_EXISTING, | 703 OPEN_EXISTING, |
| 720 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, | 704 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
| 721 NULL); | 705 NULL); |
| 722 if (file_handle == INVALID_HANDLE_VALUE) { | 706 if (file_handle == INVALID_HANDLE_VALUE) { |
| 723 return File::kError; | 707 return File::kError; |
| 724 } | 708 } |
| 725 int result = GetFileInformationByHandle(file_handle, &file_info[i]); | 709 int result = GetFileInformationByHandle(file_handle, &file_info[i]); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 740 return kIdentical; | 724 return kIdentical; |
| 741 } else { | 725 } else { |
| 742 return kDifferent; | 726 return kDifferent; |
| 743 } | 727 } |
| 744 } | 728 } |
| 745 | 729 |
| 746 } // namespace bin | 730 } // namespace bin |
| 747 } // namespace dart | 731 } // namespace dart |
| 748 | 732 |
| 749 #endif // defined(TARGET_OS_WINDOWS) | 733 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |