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 |