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 |