| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/directory.h" | 8 #include "bin/directory.h" |
| 9 #include "bin/file.h" | 9 #include "bin/file.h" |
| 10 #include "bin/utils.h" | 10 #include "bin/utils.h" |
| 11 #include "bin/utils_win.h" | 11 #include "bin/utils_win.h" |
| 12 | 12 |
| 13 #include <errno.h> // NOLINT | 13 #include <errno.h> // NOLINT |
| 14 #include <sys/stat.h> // NOLINT | 14 #include <sys/stat.h> // NOLINT |
| 15 | 15 |
| 16 #include "bin/dartutils.h" | 16 #include "bin/dartutils.h" |
| 17 #include "bin/log.h" | 17 #include "bin/log.h" |
| 18 | 18 |
| 19 #undef DeleteFile | 19 #undef DeleteFile |
| 20 | 20 |
| 21 #define MAX_LONG_PATH 32767 | 21 #define MAX_LONG_PATH 32767 |
| 22 | 22 |
| 23 namespace dart { | 23 namespace dart { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 50 | 50 |
| 51 | 51 |
| 52 bool PathBuffer::Add(const char* name) { | 52 bool PathBuffer::Add(const char* name) { |
| 53 Utf8ToWideScope wide_name(name); | 53 Utf8ToWideScope wide_name(name); |
| 54 return AddW(wide_name.wide()); | 54 return AddW(wide_name.wide()); |
| 55 } | 55 } |
| 56 | 56 |
| 57 | 57 |
| 58 bool PathBuffer::AddW(const wchar_t* name) { | 58 bool PathBuffer::AddW(const wchar_t* name) { |
| 59 wchar_t* data = AsStringW(); | 59 wchar_t* data = AsStringW(); |
| 60 int written = _snwprintf(data + length_, | 60 int written = |
| 61 MAX_LONG_PATH - length_, | 61 _snwprintf(data + length_, MAX_LONG_PATH - length_, L"%s", name); |
| 62 L"%s", | |
| 63 name); | |
| 64 data[MAX_LONG_PATH] = L'\0'; | 62 data[MAX_LONG_PATH] = L'\0'; |
| 65 if ((written <= MAX_LONG_PATH - length_) && | 63 if ((written <= MAX_LONG_PATH - length_) && (written >= 0) && |
| 66 (written >= 0) && | |
| 67 (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) { | 64 (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) { |
| 68 length_ += written; | 65 length_ += written; |
| 69 return true; | 66 return true; |
| 70 } else { | 67 } else { |
| 71 SetLastError(ERROR_BUFFER_OVERFLOW); | 68 SetLastError(ERROR_BUFFER_OVERFLOW); |
| 72 return false; | 69 return false; |
| 73 } | 70 } |
| 74 } | 71 } |
| 75 | 72 |
| 76 | 73 |
| 77 void PathBuffer::Reset(intptr_t new_length) { | 74 void PathBuffer::Reset(intptr_t new_length) { |
| 78 length_ = new_length; | 75 length_ = new_length; |
| 79 AsStringW()[length_] = L'\0'; | 76 AsStringW()[length_] = L'\0'; |
| 80 } | 77 } |
| 81 | 78 |
| 82 | 79 |
| 83 // If link_name points to a link, IsBrokenLink will return true if link_name | 80 // If link_name points to a link, IsBrokenLink will return true if link_name |
| 84 // points to an invalid target. | 81 // points to an invalid target. |
| 85 static bool IsBrokenLink(const wchar_t* link_name) { | 82 static bool IsBrokenLink(const wchar_t* link_name) { |
| 86 HANDLE handle = CreateFileW( | 83 HANDLE handle = CreateFileW( |
| 87 link_name, | 84 link_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 88 0, | 85 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 89 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | |
| 90 NULL, | |
| 91 OPEN_EXISTING, | |
| 92 FILE_FLAG_BACKUP_SEMANTICS, | |
| 93 NULL); | |
| 94 if (handle == INVALID_HANDLE_VALUE) { | 86 if (handle == INVALID_HANDLE_VALUE) { |
| 95 return true; | 87 return true; |
| 96 } else { | 88 } else { |
| 97 CloseHandle(handle); | 89 CloseHandle(handle); |
| 98 return false; | 90 return false; |
| 99 } | 91 } |
| 100 } | 92 } |
| 101 | 93 |
| 102 | 94 |
| 103 // A linked list structure holding a link target's unique file system ID. | 95 // A linked list structure holding a link target's unique file system ID. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 117 DirectoryListingEntry* entry, | 109 DirectoryListingEntry* entry, |
| 118 const WIN32_FIND_DATAW& find_file_data) { | 110 const WIN32_FIND_DATAW& find_file_data) { |
| 119 if (!listing->path_buffer().AddW(find_file_data.cFileName)) { | 111 if (!listing->path_buffer().AddW(find_file_data.cFileName)) { |
| 120 return kListError; | 112 return kListError; |
| 121 } | 113 } |
| 122 DWORD attributes = find_file_data.dwFileAttributes; | 114 DWORD attributes = find_file_data.dwFileAttributes; |
| 123 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 115 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 124 if (!listing->follow_links()) { | 116 if (!listing->follow_links()) { |
| 125 return kListLink; | 117 return kListLink; |
| 126 } | 118 } |
| 127 HANDLE handle = CreateFileW( | 119 HANDLE handle = |
| 128 listing->path_buffer().AsStringW(), | 120 CreateFileW(listing->path_buffer().AsStringW(), 0, |
| 129 0, | 121 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 130 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 122 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 131 NULL, | |
| 132 OPEN_EXISTING, | |
| 133 FILE_FLAG_BACKUP_SEMANTICS, | |
| 134 NULL); | |
| 135 if (handle == INVALID_HANDLE_VALUE) { | 123 if (handle == INVALID_HANDLE_VALUE) { |
| 136 // Report as (broken) link. | 124 // Report as (broken) link. |
| 137 return kListLink; | 125 return kListLink; |
| 138 } | 126 } |
| 139 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 127 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 140 // Check the seen link targets to see if we are in a file system loop. | 128 // Check the seen link targets to see if we are in a file system loop. |
| 141 LinkList current_link; | 129 LinkList current_link; |
| 142 BY_HANDLE_FILE_INFORMATION info; | 130 BY_HANDLE_FILE_INFORMATION info; |
| 143 // Get info | 131 // Get info |
| 144 if (!GetFileInformationByHandle(handle, &info)) { | 132 if (!GetFileInformationByHandle(handle, &info)) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 | 180 |
| 193 if (lister_ == 0) { | 181 if (lister_ == 0) { |
| 194 const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*"; | 182 const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*"; |
| 195 if (!listing->path_buffer().AddW(tail)) { | 183 if (!listing->path_buffer().AddW(tail)) { |
| 196 done_ = true; | 184 done_ = true; |
| 197 return kListError; | 185 return kListError; |
| 198 } | 186 } |
| 199 | 187 |
| 200 path_length_ = listing->path_buffer().length() - 1; | 188 path_length_ = listing->path_buffer().length() - 1; |
| 201 | 189 |
| 202 HANDLE find_handle = FindFirstFileW(listing->path_buffer().AsStringW(), | 190 HANDLE find_handle = |
| 203 &find_file_data); | 191 FindFirstFileW(listing->path_buffer().AsStringW(), &find_file_data); |
| 204 | 192 |
| 205 if (find_handle == INVALID_HANDLE_VALUE) { | 193 if (find_handle == INVALID_HANDLE_VALUE) { |
| 206 done_ = true; | 194 done_ = true; |
| 207 return kListError; | 195 return kListError; |
| 208 } | 196 } |
| 209 | 197 |
| 210 lister_ = reinterpret_cast<intptr_t>(find_handle); | 198 lister_ = reinterpret_cast<intptr_t>(find_handle); |
| 211 | 199 |
| 212 listing->path_buffer().Reset(path_length_); | 200 listing->path_buffer().Reset(path_length_); |
| 213 | 201 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 266 |
| 279 return DeleteFileW(path->AsStringW()) != 0; | 267 return DeleteFileW(path->AsStringW()) != 0; |
| 280 } | 268 } |
| 281 } | 269 } |
| 282 | 270 |
| 283 return false; | 271 return false; |
| 284 } | 272 } |
| 285 | 273 |
| 286 | 274 |
| 287 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { | 275 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { |
| 288 if ((wcscmp(dir_name, L".") == 0) || | 276 if ((wcscmp(dir_name, L".") == 0) || (wcscmp(dir_name, L"..") == 0)) { |
| 289 (wcscmp(dir_name, L"..") == 0)) { | |
| 290 return true; | 277 return true; |
| 291 } | 278 } |
| 292 return path->AddW(dir_name) && DeleteRecursively(path); | 279 return path->AddW(dir_name) && DeleteRecursively(path); |
| 293 } | 280 } |
| 294 | 281 |
| 295 | 282 |
| 296 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { | 283 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { |
| 297 DWORD attributes = find_file_data->dwFileAttributes; | 284 DWORD attributes = find_file_data->dwFileAttributes; |
| 298 | 285 |
| 299 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 286 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 } | 369 } |
| 383 | 370 |
| 384 | 371 |
| 385 char* Directory::CurrentNoScope() { | 372 char* Directory::CurrentNoScope() { |
| 386 int length = GetCurrentDirectoryW(0, NULL); | 373 int length = GetCurrentDirectoryW(0, NULL); |
| 387 if (length == 0) { | 374 if (length == 0) { |
| 388 return NULL; | 375 return NULL; |
| 389 } | 376 } |
| 390 wchar_t* current = new wchar_t[length + 1]; | 377 wchar_t* current = new wchar_t[length + 1]; |
| 391 GetCurrentDirectoryW(length + 1, current); | 378 GetCurrentDirectoryW(length + 1, current); |
| 392 int utf8_len = WideCharToMultiByte( | 379 int utf8_len = |
| 393 CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL); | 380 WideCharToMultiByte(CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL); |
| 394 char* result = reinterpret_cast<char*>(malloc(utf8_len)); | 381 char* result = reinterpret_cast<char*>(malloc(utf8_len)); |
| 395 WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL); | 382 WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL); |
| 396 delete[] current; | 383 delete[] current; |
| 397 return result; | 384 return result; |
| 398 } | 385 } |
| 399 | 386 |
| 400 | 387 |
| 401 const char* Directory::Current() { | 388 const char* Directory::Current() { |
| 402 int length = GetCurrentDirectoryW(0, NULL); | 389 int length = GetCurrentDirectoryW(0, NULL); |
| 403 if (length == 0) { | 390 if (length == 0) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 415 Utf8ToWideScope system_path(path); | 402 Utf8ToWideScope system_path(path); |
| 416 bool result = SetCurrentDirectoryW(system_path.wide()) != 0; | 403 bool result = SetCurrentDirectoryW(system_path.wide()) != 0; |
| 417 return result; | 404 return result; |
| 418 } | 405 } |
| 419 | 406 |
| 420 | 407 |
| 421 bool Directory::Create(const char* dir_name) { | 408 bool Directory::Create(const char* dir_name) { |
| 422 Utf8ToWideScope system_name(dir_name); | 409 Utf8ToWideScope system_name(dir_name); |
| 423 int create_status = CreateDirectoryW(system_name.wide(), NULL); | 410 int create_status = CreateDirectoryW(system_name.wide(), NULL); |
| 424 // If the directory already existed, treat it as a success. | 411 // If the directory already existed, treat it as a success. |
| 425 if ((create_status == 0) && | 412 if ((create_status == 0) && (GetLastError() == ERROR_ALREADY_EXISTS) && |
| 426 (GetLastError() == ERROR_ALREADY_EXISTS) && | |
| 427 (ExistsHelper(system_name.wide()) == EXISTS)) { | 413 (ExistsHelper(system_name.wide()) == EXISTS)) { |
| 428 return true; | 414 return true; |
| 429 } | 415 } |
| 430 return (create_status != 0); | 416 return (create_status != 0); |
| 431 } | 417 } |
| 432 | 418 |
| 433 | 419 |
| 434 const char* Directory::SystemTemp() { | 420 const char* Directory::SystemTemp() { |
| 435 PathBuffer path; | 421 PathBuffer path; |
| 436 // Remove \ at end. | 422 // Remove \ at end. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 DWORD flags = MOVEFILE_WRITE_THROUGH; | 504 DWORD flags = MOVEFILE_WRITE_THROUGH; |
| 519 int move_status = | 505 int move_status = |
| 520 MoveFileExW(system_path.wide(), system_new_path.wide(), flags); | 506 MoveFileExW(system_path.wide(), system_new_path.wide(), flags); |
| 521 return (move_status != 0); | 507 return (move_status != 0); |
| 522 } | 508 } |
| 523 | 509 |
| 524 } // namespace bin | 510 } // namespace bin |
| 525 } // namespace dart | 511 } // namespace dart |
| 526 | 512 |
| 527 #endif // defined(TARGET_OS_WINDOWS) | 513 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |