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(HOST_OS_WINDOWS) | 6 #if defined(HOST_OS_WINDOWS) |
7 | 7 |
8 #include "bin/file.h" | 8 #include "bin/file.h" |
9 | 9 |
| 10 #include <WinIoCtl.h> // NOLINT |
10 #include <fcntl.h> // NOLINT | 11 #include <fcntl.h> // NOLINT |
11 #include <io.h> // NOLINT | 12 #include <io.h> // NOLINT |
12 #include <stdio.h> // NOLINT | 13 #include <stdio.h> // NOLINT |
13 #include <string.h> // NOLINT | 14 #include <string.h> // NOLINT |
14 #include <sys/stat.h> // NOLINT | 15 #include <sys/stat.h> // NOLINT |
15 #include <sys/utime.h> // NOLINT | 16 #include <sys/utime.h> // NOLINT |
16 #include <WinIoCtl.h> // NOLINT | |
17 | 17 |
18 #include "bin/builtin.h" | 18 #include "bin/builtin.h" |
19 #include "bin/log.h" | 19 #include "bin/log.h" |
20 #include "bin/utils.h" | 20 #include "bin/utils.h" |
21 #include "bin/utils_win.h" | 21 #include "bin/utils_win.h" |
22 #include "platform/utils.h" | 22 #include "platform/utils.h" |
23 | 23 |
24 namespace dart { | 24 namespace dart { |
25 namespace bin { | 25 namespace bin { |
26 | 26 |
27 class FileHandle { | 27 class FileHandle { |
28 public: | 28 public: |
29 explicit FileHandle(int fd) : fd_(fd) {} | 29 explicit FileHandle(int fd) : fd_(fd) {} |
30 ~FileHandle() {} | 30 ~FileHandle() {} |
31 int fd() const { return fd_; } | 31 int fd() const { return fd_; } |
32 void set_fd(int fd) { fd_ = fd; } | 32 void set_fd(int fd) { fd_ = fd; } |
33 | 33 |
34 private: | 34 private: |
35 int fd_; | 35 int fd_; |
36 | 36 |
37 DISALLOW_COPY_AND_ASSIGN(FileHandle); | 37 DISALLOW_COPY_AND_ASSIGN(FileHandle); |
38 }; | 38 }; |
39 | 39 |
40 | |
41 File::~File() { | 40 File::~File() { |
42 if (!IsClosed() && handle_->fd() != _fileno(stdout) && | 41 if (!IsClosed() && handle_->fd() != _fileno(stdout) && |
43 handle_->fd() != _fileno(stderr)) { | 42 handle_->fd() != _fileno(stderr)) { |
44 Close(); | 43 Close(); |
45 } | 44 } |
46 delete handle_; | 45 delete handle_; |
47 } | 46 } |
48 | 47 |
49 | |
50 void File::Close() { | 48 void File::Close() { |
51 ASSERT(handle_->fd() >= 0); | 49 ASSERT(handle_->fd() >= 0); |
52 int closing_fd = handle_->fd(); | 50 int closing_fd = handle_->fd(); |
53 if ((closing_fd == _fileno(stdout)) || (closing_fd == _fileno(stderr))) { | 51 if ((closing_fd == _fileno(stdout)) || (closing_fd == _fileno(stderr))) { |
54 int fd = _open("NUL", _O_WRONLY); | 52 int fd = _open("NUL", _O_WRONLY); |
55 ASSERT(fd >= 0); | 53 ASSERT(fd >= 0); |
56 _dup2(fd, closing_fd); | 54 _dup2(fd, closing_fd); |
57 close(fd); | 55 close(fd); |
58 } else { | 56 } else { |
59 int err = close(closing_fd); | 57 int err = close(closing_fd); |
60 if (err != 0) { | 58 if (err != 0) { |
61 Log::PrintErr("%s\n", strerror(errno)); | 59 Log::PrintErr("%s\n", strerror(errno)); |
62 } | 60 } |
63 } | 61 } |
64 handle_->set_fd(kClosedFd); | 62 handle_->set_fd(kClosedFd); |
65 } | 63 } |
66 | 64 |
67 | |
68 intptr_t File::GetFD() { | 65 intptr_t File::GetFD() { |
69 return handle_->fd(); | 66 return handle_->fd(); |
70 } | 67 } |
71 | 68 |
72 | |
73 bool File::IsClosed() { | 69 bool File::IsClosed() { |
74 return handle_->fd() == kClosedFd; | 70 return handle_->fd() == kClosedFd; |
75 } | 71 } |
76 | 72 |
77 | |
78 MappedMemory* File::Map(File::MapType type, int64_t position, int64_t length) { | 73 MappedMemory* File::Map(File::MapType type, int64_t position, int64_t length) { |
79 DWORD prot_alloc; | 74 DWORD prot_alloc; |
80 DWORD prot_final; | 75 DWORD prot_final; |
81 switch (type) { | 76 switch (type) { |
82 case File::kReadOnly: | 77 case File::kReadOnly: |
83 prot_alloc = PAGE_READWRITE; | 78 prot_alloc = PAGE_READWRITE; |
84 prot_final = PAGE_READONLY; | 79 prot_final = PAGE_READONLY; |
85 break; | 80 break; |
86 case File::kReadExecute: | 81 case File::kReadExecute: |
87 prot_alloc = PAGE_EXECUTE_READWRITE; | 82 prot_alloc = PAGE_EXECUTE_READWRITE; |
(...skipping 19 matching lines...) Expand all Loading... |
107 DWORD old_prot; | 102 DWORD old_prot; |
108 bool result = VirtualProtect(addr, length, prot_final, &old_prot); | 103 bool result = VirtualProtect(addr, length, prot_final, &old_prot); |
109 if (!result) { | 104 if (!result) { |
110 Log::PrintErr("VirtualProtect failed %d\n", GetLastError()); | 105 Log::PrintErr("VirtualProtect failed %d\n", GetLastError()); |
111 VirtualFree(addr, 0, MEM_RELEASE); | 106 VirtualFree(addr, 0, MEM_RELEASE); |
112 return NULL; | 107 return NULL; |
113 } | 108 } |
114 return new MappedMemory(addr, length); | 109 return new MappedMemory(addr, length); |
115 } | 110 } |
116 | 111 |
117 | |
118 void MappedMemory::Unmap() { | 112 void MappedMemory::Unmap() { |
119 BOOL result = VirtualFree(address_, 0, MEM_RELEASE); | 113 BOOL result = VirtualFree(address_, 0, MEM_RELEASE); |
120 ASSERT(result); | 114 ASSERT(result); |
121 address_ = 0; | 115 address_ = 0; |
122 size_ = 0; | 116 size_ = 0; |
123 } | 117 } |
124 | 118 |
125 | |
126 int64_t File::Read(void* buffer, int64_t num_bytes) { | 119 int64_t File::Read(void* buffer, int64_t num_bytes) { |
127 ASSERT(handle_->fd() >= 0); | 120 ASSERT(handle_->fd() >= 0); |
128 return read(handle_->fd(), buffer, num_bytes); | 121 return read(handle_->fd(), buffer, num_bytes); |
129 } | 122 } |
130 | 123 |
131 | |
132 int64_t File::Write(const void* buffer, int64_t num_bytes) { | 124 int64_t File::Write(const void* buffer, int64_t num_bytes) { |
133 int fd = handle_->fd(); | 125 int fd = handle_->fd(); |
134 ASSERT(fd >= 0); | 126 ASSERT(fd >= 0); |
135 HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); | 127 HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); |
136 DWORD written = 0; | 128 DWORD written = 0; |
137 BOOL result = WriteFile(handle, buffer, num_bytes, &written, NULL); | 129 BOOL result = WriteFile(handle, buffer, num_bytes, &written, NULL); |
138 if (!result) { | 130 if (!result) { |
139 return -1; | 131 return -1; |
140 } | 132 } |
141 DWORD mode; | 133 DWORD mode; |
(...skipping 12 matching lines...) Expand all Loading... |
154 MultiByteToWideChar(cp, 0, reinterpret_cast<const char*>(buffer), -1, wide, | 146 MultiByteToWideChar(cp, 0, reinterpret_cast<const char*>(buffer), -1, wide, |
155 written); | 147 written); |
156 int buffer_len = | 148 int buffer_len = |
157 WideCharToMultiByte(cp, 0, wide, written, NULL, 0, NULL, NULL); | 149 WideCharToMultiByte(cp, 0, wide, written, NULL, 0, NULL, NULL); |
158 delete wide; | 150 delete wide; |
159 bytes_written = buffer_len; | 151 bytes_written = buffer_len; |
160 } | 152 } |
161 return bytes_written; | 153 return bytes_written; |
162 } | 154 } |
163 | 155 |
164 | |
165 bool File::VPrint(const char* format, va_list args) { | 156 bool File::VPrint(const char* format, va_list args) { |
166 // Measure. | 157 // Measure. |
167 va_list measure_args; | 158 va_list measure_args; |
168 va_copy(measure_args, args); | 159 va_copy(measure_args, args); |
169 intptr_t len = _vscprintf(format, measure_args); | 160 intptr_t len = _vscprintf(format, measure_args); |
170 va_end(measure_args); | 161 va_end(measure_args); |
171 | 162 |
172 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); | 163 char* buffer = reinterpret_cast<char*>(malloc(len + 1)); |
173 | 164 |
174 // Print. | 165 // Print. |
175 va_list print_args; | 166 va_list print_args; |
176 va_copy(print_args, args); | 167 va_copy(print_args, args); |
177 _vsnprintf(buffer, len + 1, format, print_args); | 168 _vsnprintf(buffer, len + 1, format, print_args); |
178 va_end(print_args); | 169 va_end(print_args); |
179 | 170 |
180 bool result = WriteFully(buffer, len); | 171 bool result = WriteFully(buffer, len); |
181 free(buffer); | 172 free(buffer); |
182 return result; | 173 return result; |
183 } | 174 } |
184 | 175 |
185 | |
186 int64_t File::Position() { | 176 int64_t File::Position() { |
187 ASSERT(handle_->fd() >= 0); | 177 ASSERT(handle_->fd() >= 0); |
188 return _lseeki64(handle_->fd(), 0, SEEK_CUR); | 178 return _lseeki64(handle_->fd(), 0, SEEK_CUR); |
189 } | 179 } |
190 | 180 |
191 | |
192 bool File::SetPosition(int64_t position) { | 181 bool File::SetPosition(int64_t position) { |
193 ASSERT(handle_->fd() >= 0); | 182 ASSERT(handle_->fd() >= 0); |
194 return _lseeki64(handle_->fd(), position, SEEK_SET) >= 0; | 183 return _lseeki64(handle_->fd(), position, SEEK_SET) >= 0; |
195 } | 184 } |
196 | 185 |
197 | |
198 bool File::Truncate(int64_t length) { | 186 bool File::Truncate(int64_t length) { |
199 ASSERT(handle_->fd() >= 0); | 187 ASSERT(handle_->fd() >= 0); |
200 return _chsize_s(handle_->fd(), length) == 0; | 188 return _chsize_s(handle_->fd(), length) == 0; |
201 } | 189 } |
202 | 190 |
203 | |
204 bool File::Flush() { | 191 bool File::Flush() { |
205 ASSERT(handle_->fd()); | 192 ASSERT(handle_->fd()); |
206 return _commit(handle_->fd()) != -1; | 193 return _commit(handle_->fd()) != -1; |
207 } | 194 } |
208 | 195 |
209 | |
210 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { | 196 bool File::Lock(File::LockType lock, int64_t start, int64_t end) { |
211 ASSERT(handle_->fd() >= 0); | 197 ASSERT(handle_->fd() >= 0); |
212 ASSERT((end == -1) || (end > start)); | 198 ASSERT((end == -1) || (end > start)); |
213 HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd())); | 199 HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(handle_->fd())); |
214 OVERLAPPED overlapped; | 200 OVERLAPPED overlapped; |
215 ZeroMemory(&overlapped, sizeof(OVERLAPPED)); | 201 ZeroMemory(&overlapped, sizeof(OVERLAPPED)); |
216 | 202 |
217 overlapped.Offset = Utils::Low32Bits(start); | 203 overlapped.Offset = Utils::Low32Bits(start); |
218 overlapped.OffsetHigh = Utils::High32Bits(start); | 204 overlapped.OffsetHigh = Utils::High32Bits(start); |
219 | 205 |
(...skipping 23 matching lines...) Expand all Loading... |
243 } | 229 } |
244 rc = LockFileEx(handle, flags, 0, length_low, length_high, &overlapped); | 230 rc = LockFileEx(handle, flags, 0, length_low, length_high, &overlapped); |
245 break; | 231 break; |
246 } | 232 } |
247 default: | 233 default: |
248 UNREACHABLE(); | 234 UNREACHABLE(); |
249 } | 235 } |
250 return rc; | 236 return rc; |
251 } | 237 } |
252 | 238 |
253 | |
254 int64_t File::Length() { | 239 int64_t File::Length() { |
255 ASSERT(handle_->fd() >= 0); | 240 ASSERT(handle_->fd() >= 0); |
256 struct __stat64 st; | 241 struct __stat64 st; |
257 if (_fstat64(handle_->fd(), &st) == 0) { | 242 if (_fstat64(handle_->fd(), &st) == 0) { |
258 return st.st_size; | 243 return st.st_size; |
259 } | 244 } |
260 return -1; | 245 return -1; |
261 } | 246 } |
262 | 247 |
263 | |
264 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { | 248 File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) { |
265 int flags = O_RDONLY | O_BINARY | O_NOINHERIT; | 249 int flags = O_RDONLY | O_BINARY | O_NOINHERIT; |
266 if ((mode & kWrite) != 0) { | 250 if ((mode & kWrite) != 0) { |
267 ASSERT((mode & kWriteOnly) == 0); | 251 ASSERT((mode & kWriteOnly) == 0); |
268 flags = (O_RDWR | O_CREAT | O_BINARY | O_NOINHERIT); | 252 flags = (O_RDWR | O_CREAT | O_BINARY | O_NOINHERIT); |
269 } | 253 } |
270 if ((mode & kWriteOnly) != 0) { | 254 if ((mode & kWriteOnly) != 0) { |
271 ASSERT((mode & kWrite) == 0); | 255 ASSERT((mode & kWrite) == 0); |
272 flags = (O_WRONLY | O_CREAT | O_BINARY | O_NOINHERIT); | 256 flags = (O_WRONLY | O_CREAT | O_BINARY | O_NOINHERIT); |
273 } | 257 } |
274 if ((mode & kTruncate) != 0) { | 258 if ((mode & kTruncate) != 0) { |
275 flags = flags | O_TRUNC; | 259 flags = flags | O_TRUNC; |
276 } | 260 } |
277 int fd = _wopen(system_name, flags, 0666); | 261 int fd = _wopen(system_name, flags, 0666); |
278 if (fd < 0) { | 262 if (fd < 0) { |
279 return NULL; | 263 return NULL; |
280 } | 264 } |
281 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) || | 265 if ((((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) || |
282 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { | 266 (((mode & kWriteOnly) != 0) && ((mode & kTruncate) == 0))) { |
283 int64_t position = _lseeki64(fd, 0, SEEK_END); | 267 int64_t position = _lseeki64(fd, 0, SEEK_END); |
284 if (position < 0) { | 268 if (position < 0) { |
285 return NULL; | 269 return NULL; |
286 } | 270 } |
287 } | 271 } |
288 return new File(new FileHandle(fd)); | 272 return new File(new FileHandle(fd)); |
289 } | 273 } |
290 | 274 |
291 | |
292 File* File::Open(const char* path, FileOpenMode mode) { | 275 File* File::Open(const char* path, FileOpenMode mode) { |
293 Utf8ToWideScope system_name(path); | 276 Utf8ToWideScope system_name(path); |
294 File* file = FileOpenW(system_name.wide(), mode); | 277 File* file = FileOpenW(system_name.wide(), mode); |
295 return file; | 278 return file; |
296 } | 279 } |
297 | 280 |
298 | |
299 File* File::OpenStdio(int fd) { | 281 File* File::OpenStdio(int fd) { |
300 int stdio_fd = -1; | 282 int stdio_fd = -1; |
301 switch (fd) { | 283 switch (fd) { |
302 case 1: | 284 case 1: |
303 stdio_fd = _fileno(stdout); | 285 stdio_fd = _fileno(stdout); |
304 break; | 286 break; |
305 case 2: | 287 case 2: |
306 stdio_fd = _fileno(stderr); | 288 stdio_fd = _fileno(stderr); |
307 break; | 289 break; |
308 default: | 290 default: |
309 UNREACHABLE(); | 291 UNREACHABLE(); |
310 } | 292 } |
311 _setmode(stdio_fd, _O_BINARY); | 293 _setmode(stdio_fd, _O_BINARY); |
312 return new File(new FileHandle(stdio_fd)); | 294 return new File(new FileHandle(stdio_fd)); |
313 } | 295 } |
314 | 296 |
315 | |
316 static bool StatHelper(wchar_t* path, struct __stat64* st) { | 297 static bool StatHelper(wchar_t* path, struct __stat64* st) { |
317 int stat_status = _wstat64(path, st); | 298 int stat_status = _wstat64(path, st); |
318 if (stat_status != 0) { | 299 if (stat_status != 0) { |
319 return false; | 300 return false; |
320 } | 301 } |
321 if ((st->st_mode & S_IFMT) != S_IFREG) { | 302 if ((st->st_mode & S_IFMT) != S_IFREG) { |
322 SetLastError(ERROR_NOT_SUPPORTED); | 303 SetLastError(ERROR_NOT_SUPPORTED); |
323 return false; | 304 return false; |
324 } | 305 } |
325 return true; | 306 return true; |
326 } | 307 } |
327 | 308 |
328 | |
329 bool File::Exists(const char* name) { | 309 bool File::Exists(const char* name) { |
330 struct __stat64 st; | 310 struct __stat64 st; |
331 Utf8ToWideScope system_name(name); | 311 Utf8ToWideScope system_name(name); |
332 return StatHelper(system_name.wide(), &st); | 312 return StatHelper(system_name.wide(), &st); |
333 } | 313 } |
334 | 314 |
335 | |
336 bool File::Create(const char* name) { | 315 bool File::Create(const char* name) { |
337 Utf8ToWideScope system_name(name); | 316 Utf8ToWideScope system_name(name); |
338 int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 0666); | 317 int fd = _wopen(system_name.wide(), O_RDONLY | O_CREAT, 0666); |
339 if (fd < 0) { | 318 if (fd < 0) { |
340 return false; | 319 return false; |
341 } | 320 } |
342 return (close(fd) == 0); | 321 return (close(fd) == 0); |
343 } | 322 } |
344 | 323 |
345 | |
346 // This structure is needed for creating and reading Junctions. | 324 // This structure is needed for creating and reading Junctions. |
347 typedef struct _REPARSE_DATA_BUFFER { | 325 typedef struct _REPARSE_DATA_BUFFER { |
348 ULONG ReparseTag; | 326 ULONG ReparseTag; |
349 USHORT ReparseDataLength; | 327 USHORT ReparseDataLength; |
350 USHORT Reserved; | 328 USHORT Reserved; |
351 | 329 |
352 union { | 330 union { |
353 struct { | 331 struct { |
354 USHORT SubstituteNameOffset; | 332 USHORT SubstituteNameOffset; |
355 USHORT SubstituteNameLength; | 333 USHORT SubstituteNameLength; |
(...skipping 10 matching lines...) Expand all Loading... |
366 USHORT PrintNameLength; | 344 USHORT PrintNameLength; |
367 WCHAR PathBuffer[1]; | 345 WCHAR PathBuffer[1]; |
368 } MountPointReparseBuffer; | 346 } MountPointReparseBuffer; |
369 | 347 |
370 struct { | 348 struct { |
371 UCHAR DataBuffer[1]; | 349 UCHAR DataBuffer[1]; |
372 } GenericReparseBuffer; | 350 } GenericReparseBuffer; |
373 }; | 351 }; |
374 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; | 352 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; |
375 | 353 |
376 | |
377 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT; | 354 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT; |
378 static const int kMountPointHeaderSize = 4 * sizeof USHORT; | 355 static const int kMountPointHeaderSize = 4 * sizeof USHORT; |
379 | 356 |
380 | |
381 bool File::CreateLink(const char* utf8_name, const char* utf8_target) { | 357 bool File::CreateLink(const char* utf8_name, const char* utf8_target) { |
382 Utf8ToWideScope name(utf8_name); | 358 Utf8ToWideScope name(utf8_name); |
383 int create_status = CreateDirectoryW(name.wide(), NULL); | 359 int create_status = CreateDirectoryW(name.wide(), NULL); |
384 // If the directory already existed, treat it as a success. | 360 // If the directory already existed, treat it as a success. |
385 if ((create_status == 0) && | 361 if ((create_status == 0) && |
386 ((GetLastError() != ERROR_ALREADY_EXISTS) || | 362 ((GetLastError() != ERROR_ALREADY_EXISTS) || |
387 ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { | 363 ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) { |
388 return false; | 364 return false; |
389 } | 365 } |
390 | 366 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 dir_handle, FSCTL_SET_REPARSE_POINT, reparse_data_buffer, | 404 dir_handle, FSCTL_SET_REPARSE_POINT, reparse_data_buffer, |
429 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, NULL, 0, | 405 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, NULL, 0, |
430 &dummy_received_bytes, NULL); | 406 &dummy_received_bytes, NULL); |
431 free(reparse_data_buffer); | 407 free(reparse_data_buffer); |
432 if (CloseHandle(dir_handle) == 0) { | 408 if (CloseHandle(dir_handle) == 0) { |
433 return false; | 409 return false; |
434 } | 410 } |
435 return (result != 0); | 411 return (result != 0); |
436 } | 412 } |
437 | 413 |
438 | |
439 bool File::Delete(const char* name) { | 414 bool File::Delete(const char* name) { |
440 Utf8ToWideScope system_name(name); | 415 Utf8ToWideScope system_name(name); |
441 int status = _wremove(system_name.wide()); | 416 int status = _wremove(system_name.wide()); |
442 return status != -1; | 417 return status != -1; |
443 } | 418 } |
444 | 419 |
445 | |
446 bool File::DeleteLink(const char* name) { | 420 bool File::DeleteLink(const char* name) { |
447 Utf8ToWideScope system_name(name); | 421 Utf8ToWideScope system_name(name); |
448 bool result = false; | 422 bool result = false; |
449 DWORD attributes = GetFileAttributesW(system_name.wide()); | 423 DWORD attributes = GetFileAttributesW(system_name.wide()); |
450 if ((attributes != INVALID_FILE_ATTRIBUTES) && | 424 if ((attributes != INVALID_FILE_ATTRIBUTES) && |
451 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 425 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
452 // It's a junction(link), delete it. | 426 // It's a junction(link), delete it. |
453 result = (RemoveDirectoryW(system_name.wide()) != 0); | 427 result = (RemoveDirectoryW(system_name.wide()) != 0); |
454 } else { | 428 } else { |
455 SetLastError(ERROR_NOT_A_REPARSE_POINT); | 429 SetLastError(ERROR_NOT_A_REPARSE_POINT); |
456 } | 430 } |
457 return result; | 431 return result; |
458 } | 432 } |
459 | 433 |
460 | |
461 bool File::Rename(const char* old_path, const char* new_path) { | 434 bool File::Rename(const char* old_path, const char* new_path) { |
462 File::Type type = GetType(old_path, false); | 435 File::Type type = GetType(old_path, false); |
463 if (type == kIsFile) { | 436 if (type == kIsFile) { |
464 Utf8ToWideScope system_old_path(old_path); | 437 Utf8ToWideScope system_old_path(old_path); |
465 Utf8ToWideScope system_new_path(new_path); | 438 Utf8ToWideScope system_new_path(new_path); |
466 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; | 439 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; |
467 int move_status = | 440 int move_status = |
468 MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); | 441 MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); |
469 return (move_status != 0); | 442 return (move_status != 0); |
470 } else { | 443 } else { |
471 SetLastError(ERROR_FILE_NOT_FOUND); | 444 SetLastError(ERROR_FILE_NOT_FOUND); |
472 } | 445 } |
473 return false; | 446 return false; |
474 } | 447 } |
475 | 448 |
476 | |
477 bool File::RenameLink(const char* old_path, const char* new_path) { | 449 bool File::RenameLink(const char* old_path, const char* new_path) { |
478 File::Type type = GetType(old_path, false); | 450 File::Type type = GetType(old_path, false); |
479 if (type == kIsLink) { | 451 if (type == kIsLink) { |
480 Utf8ToWideScope system_old_path(old_path); | 452 Utf8ToWideScope system_old_path(old_path); |
481 Utf8ToWideScope system_new_path(new_path); | 453 Utf8ToWideScope system_new_path(new_path); |
482 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; | 454 DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING; |
483 int move_status = | 455 int move_status = |
484 MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); | 456 MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags); |
485 return (move_status != 0); | 457 return (move_status != 0); |
486 } else { | 458 } else { |
487 SetLastError(ERROR_FILE_NOT_FOUND); | 459 SetLastError(ERROR_FILE_NOT_FOUND); |
488 } | 460 } |
489 return false; | 461 return false; |
490 } | 462 } |
491 | 463 |
492 | |
493 bool File::Copy(const char* old_path, const char* new_path) { | 464 bool File::Copy(const char* old_path, const char* new_path) { |
494 File::Type type = GetType(old_path, false); | 465 File::Type type = GetType(old_path, false); |
495 if (type == kIsFile) { | 466 if (type == kIsFile) { |
496 Utf8ToWideScope system_old_path(old_path); | 467 Utf8ToWideScope system_old_path(old_path); |
497 Utf8ToWideScope system_new_path(new_path); | 468 Utf8ToWideScope system_new_path(new_path); |
498 bool success = CopyFileExW(system_old_path.wide(), system_new_path.wide(), | 469 bool success = CopyFileExW(system_old_path.wide(), system_new_path.wide(), |
499 NULL, NULL, NULL, 0) != 0; | 470 NULL, NULL, NULL, 0) != 0; |
500 return success; | 471 return success; |
501 } else { | 472 } else { |
502 SetLastError(ERROR_FILE_NOT_FOUND); | 473 SetLastError(ERROR_FILE_NOT_FOUND); |
503 } | 474 } |
504 return false; | 475 return false; |
505 } | 476 } |
506 | 477 |
507 | |
508 int64_t File::LengthFromPath(const char* name) { | 478 int64_t File::LengthFromPath(const char* name) { |
509 struct __stat64 st; | 479 struct __stat64 st; |
510 Utf8ToWideScope system_name(name); | 480 Utf8ToWideScope system_name(name); |
511 if (!StatHelper(system_name.wide(), &st)) { | 481 if (!StatHelper(system_name.wide(), &st)) { |
512 return -1; | 482 return -1; |
513 } | 483 } |
514 return st.st_size; | 484 return st.st_size; |
515 } | 485 } |
516 | 486 |
517 | |
518 const char* File::LinkTarget(const char* pathname) { | 487 const char* File::LinkTarget(const char* pathname) { |
519 const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname); | 488 const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname); |
520 HANDLE dir_handle = CreateFileW( | 489 HANDLE dir_handle = CreateFileW( |
521 name, GENERIC_READ, | 490 name, GENERIC_READ, |
522 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, | 491 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
523 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, | 492 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
524 NULL); | 493 NULL); |
525 if (dir_handle == INVALID_HANDLE_VALUE) { | 494 if (dir_handle == INVALID_HANDLE_VALUE) { |
526 return NULL; | 495 return NULL; |
527 } | 496 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 0, NULL, NULL); | 540 0, NULL, NULL); |
572 char* utf8_target = DartUtils::ScopedCString(utf8_length + 1); | 541 char* utf8_target = DartUtils::ScopedCString(utf8_length + 1); |
573 if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, utf8_target, | 542 if (0 == WideCharToMultiByte(CP_UTF8, 0, target, target_length, utf8_target, |
574 utf8_length, NULL, NULL)) { | 543 utf8_length, NULL, NULL)) { |
575 return NULL; | 544 return NULL; |
576 } | 545 } |
577 utf8_target[utf8_length] = '\0'; | 546 utf8_target[utf8_length] = '\0'; |
578 return utf8_target; | 547 return utf8_target; |
579 } | 548 } |
580 | 549 |
581 | |
582 void File::Stat(const char* name, int64_t* data) { | 550 void File::Stat(const char* name, int64_t* data) { |
583 File::Type type = GetType(name, false); | 551 File::Type type = GetType(name, false); |
584 data[kType] = type; | 552 data[kType] = type; |
585 if (type != kDoesNotExist) { | 553 if (type != kDoesNotExist) { |
586 struct _stat64 st; | 554 struct _stat64 st; |
587 Utf8ToWideScope system_name(name); | 555 Utf8ToWideScope system_name(name); |
588 int stat_status = _wstat64(system_name.wide(), &st); | 556 int stat_status = _wstat64(system_name.wide(), &st); |
589 if (stat_status == 0) { | 557 if (stat_status == 0) { |
590 data[kCreatedTime] = st.st_ctime * 1000; | 558 data[kCreatedTime] = st.st_ctime * 1000; |
591 data[kModifiedTime] = st.st_mtime * 1000; | 559 data[kModifiedTime] = st.st_mtime * 1000; |
592 data[kAccessedTime] = st.st_atime * 1000; | 560 data[kAccessedTime] = st.st_atime * 1000; |
593 data[kMode] = st.st_mode; | 561 data[kMode] = st.st_mode; |
594 data[kSize] = st.st_size; | 562 data[kSize] = st.st_size; |
595 } else { | 563 } else { |
596 data[kType] = File::kDoesNotExist; | 564 data[kType] = File::kDoesNotExist; |
597 } | 565 } |
598 } | 566 } |
599 } | 567 } |
600 | 568 |
601 | |
602 time_t File::LastAccessed(const char* name) { | 569 time_t File::LastAccessed(const char* name) { |
603 struct __stat64 st; | 570 struct __stat64 st; |
604 Utf8ToWideScope system_name(name); | 571 Utf8ToWideScope system_name(name); |
605 if (!StatHelper(system_name.wide(), &st)) { | 572 if (!StatHelper(system_name.wide(), &st)) { |
606 return -1; | 573 return -1; |
607 } | 574 } |
608 return st.st_atime; | 575 return st.st_atime; |
609 } | 576 } |
610 | 577 |
611 | |
612 time_t File::LastModified(const char* name) { | 578 time_t File::LastModified(const char* name) { |
613 struct __stat64 st; | 579 struct __stat64 st; |
614 Utf8ToWideScope system_name(name); | 580 Utf8ToWideScope system_name(name); |
615 if (!StatHelper(system_name.wide(), &st)) { | 581 if (!StatHelper(system_name.wide(), &st)) { |
616 return -1; | 582 return -1; |
617 } | 583 } |
618 return st.st_mtime; | 584 return st.st_mtime; |
619 } | 585 } |
620 | 586 |
621 | |
622 bool File::SetLastAccessed(const char* name, int64_t millis) { | 587 bool File::SetLastAccessed(const char* name, int64_t millis) { |
623 // First get the current times. | 588 // First get the current times. |
624 struct __stat64 st; | 589 struct __stat64 st; |
625 Utf8ToWideScope system_name(name); | 590 Utf8ToWideScope system_name(name); |
626 if (!StatHelper(system_name.wide(), &st)) { | 591 if (!StatHelper(system_name.wide(), &st)) { |
627 return false; | 592 return false; |
628 } | 593 } |
629 | 594 |
630 // Set the new time: | 595 // Set the new time: |
631 struct __utimbuf64 times; | 596 struct __utimbuf64 times; |
632 times.actime = millis / kMillisecondsPerSecond; | 597 times.actime = millis / kMillisecondsPerSecond; |
633 times.modtime = st.st_mtime; | 598 times.modtime = st.st_mtime; |
634 return _wutime64(system_name.wide(), ×) == 0; | 599 return _wutime64(system_name.wide(), ×) == 0; |
635 } | 600 } |
636 | 601 |
637 | |
638 bool File::SetLastModified(const char* name, int64_t millis) { | 602 bool File::SetLastModified(const char* name, int64_t millis) { |
639 // First get the current times. | 603 // First get the current times. |
640 struct __stat64 st; | 604 struct __stat64 st; |
641 Utf8ToWideScope system_name(name); | 605 Utf8ToWideScope system_name(name); |
642 if (!StatHelper(system_name.wide(), &st)) { | 606 if (!StatHelper(system_name.wide(), &st)) { |
643 return false; | 607 return false; |
644 } | 608 } |
645 | 609 |
646 // Set the new time: | 610 // Set the new time: |
647 struct __utimbuf64 times; | 611 struct __utimbuf64 times; |
648 times.actime = st.st_atime; | 612 times.actime = st.st_atime; |
649 times.modtime = millis / kMillisecondsPerSecond; | 613 times.modtime = millis / kMillisecondsPerSecond; |
650 return _wutime64(system_name.wide(), ×) == 0; | 614 return _wutime64(system_name.wide(), ×) == 0; |
651 } | 615 } |
652 | 616 |
653 | |
654 bool File::IsAbsolutePath(const char* pathname) { | 617 bool File::IsAbsolutePath(const char* pathname) { |
655 // Should we consider network paths? | 618 // Should we consider network paths? |
656 if (pathname == NULL) { | 619 if (pathname == NULL) { |
657 return false; | 620 return false; |
658 } | 621 } |
659 return ((strlen(pathname) > 2) && (pathname[1] == ':') && | 622 return ((strlen(pathname) > 2) && (pathname[1] == ':') && |
660 ((pathname[2] == '\\') || (pathname[2] == '/'))); | 623 ((pathname[2] == '\\') || (pathname[2] == '/'))); |
661 } | 624 } |
662 | 625 |
663 | |
664 const char* File::GetCanonicalPath(const char* pathname) { | 626 const char* File::GetCanonicalPath(const char* pathname) { |
665 Utf8ToWideScope system_name(pathname); | 627 Utf8ToWideScope system_name(pathname); |
666 HANDLE file_handle = | 628 HANDLE file_handle = |
667 CreateFileW(system_name.wide(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, | 629 CreateFileW(system_name.wide(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, |
668 FILE_FLAG_BACKUP_SEMANTICS, NULL); | 630 FILE_FLAG_BACKUP_SEMANTICS, NULL); |
669 if (file_handle == INVALID_HANDLE_VALUE) { | 631 if (file_handle == INVALID_HANDLE_VALUE) { |
670 return NULL; | 632 return NULL; |
671 } | 633 } |
672 wchar_t dummy_buffer[1]; | 634 wchar_t dummy_buffer[1]; |
673 int required_size = | 635 int required_size = |
(...skipping 16 matching lines...) Expand all Loading... |
690 (wcsncmp(path, L"\\\\?\\", 4) == 0) && | 652 (wcsncmp(path, L"\\\\?\\", 4) == 0) && |
691 (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) { | 653 (wcsncmp(system_name.wide(), L"\\\\?\\", 4) != 0)) { |
692 result = StringUtilsWin::WideToUtf8(path + 4); | 654 result = StringUtilsWin::WideToUtf8(path + 4); |
693 } else { | 655 } else { |
694 result = StringUtilsWin::WideToUtf8(path); | 656 result = StringUtilsWin::WideToUtf8(path); |
695 } | 657 } |
696 CloseHandle(file_handle); | 658 CloseHandle(file_handle); |
697 return result; | 659 return result; |
698 } | 660 } |
699 | 661 |
700 | |
701 const char* File::PathSeparator() { | 662 const char* File::PathSeparator() { |
702 // This is already UTF-8 encoded. | 663 // This is already UTF-8 encoded. |
703 return "\\"; | 664 return "\\"; |
704 } | 665 } |
705 | 666 |
706 | |
707 const char* File::StringEscapedPathSeparator() { | 667 const char* File::StringEscapedPathSeparator() { |
708 // This is already UTF-8 encoded. | 668 // This is already UTF-8 encoded. |
709 return "\\\\"; | 669 return "\\\\"; |
710 } | 670 } |
711 | 671 |
712 | |
713 File::StdioHandleType File::GetStdioHandleType(int fd) { | 672 File::StdioHandleType File::GetStdioHandleType(int fd) { |
714 // Treat all stdio handles as pipes. The Windows event handler and | 673 // Treat all stdio handles as pipes. The Windows event handler and |
715 // socket code will handle the different handle types. | 674 // socket code will handle the different handle types. |
716 return kPipe; | 675 return kPipe; |
717 } | 676 } |
718 | 677 |
719 | |
720 File::Type File::GetType(const char* pathname, bool follow_links) { | 678 File::Type File::GetType(const char* pathname, bool follow_links) { |
721 // Convert to wchar_t string. | 679 // Convert to wchar_t string. |
722 Utf8ToWideScope name(pathname); | 680 Utf8ToWideScope name(pathname); |
723 DWORD attributes = GetFileAttributesW(name.wide()); | 681 DWORD attributes = GetFileAttributesW(name.wide()); |
724 File::Type result = kIsFile; | 682 File::Type result = kIsFile; |
725 if (attributes == INVALID_FILE_ATTRIBUTES) { | 683 if (attributes == INVALID_FILE_ATTRIBUTES) { |
726 result = kDoesNotExist; | 684 result = kDoesNotExist; |
727 } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 685 } else if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
728 if (follow_links) { | 686 if (follow_links) { |
729 HANDLE dir_handle = | 687 HANDLE dir_handle = |
730 CreateFileW(name.wide(), 0, | 688 CreateFileW(name.wide(), 0, |
731 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 689 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
732 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | 690 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
733 if (dir_handle == INVALID_HANDLE_VALUE) { | 691 if (dir_handle == INVALID_HANDLE_VALUE) { |
734 result = File::kIsLink; | 692 result = File::kIsLink; |
735 } else { | 693 } else { |
736 CloseHandle(dir_handle); | 694 CloseHandle(dir_handle); |
737 result = File::kIsDirectory; | 695 result = File::kIsDirectory; |
738 } | 696 } |
739 } else { | 697 } else { |
740 result = kIsLink; | 698 result = kIsLink; |
741 } | 699 } |
742 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 700 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
743 result = kIsDirectory; | 701 result = kIsDirectory; |
744 } | 702 } |
745 return result; | 703 return result; |
746 } | 704 } |
747 | 705 |
748 | |
749 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { | 706 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { |
750 BY_HANDLE_FILE_INFORMATION file_info[2]; | 707 BY_HANDLE_FILE_INFORMATION file_info[2]; |
751 const char* file_names[2] = {file_1, file_2}; | 708 const char* file_names[2] = {file_1, file_2}; |
752 for (int i = 0; i < 2; ++i) { | 709 for (int i = 0; i < 2; ++i) { |
753 Utf8ToWideScope wide_name(file_names[i]); | 710 Utf8ToWideScope wide_name(file_names[i]); |
754 HANDLE file_handle = CreateFileW( | 711 HANDLE file_handle = CreateFileW( |
755 wide_name.wide(), 0, | 712 wide_name.wide(), 0, |
756 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, | 713 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
757 OPEN_EXISTING, | 714 OPEN_EXISTING, |
758 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); | 715 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
(...skipping 18 matching lines...) Expand all Loading... |
777 return kIdentical; | 734 return kIdentical; |
778 } else { | 735 } else { |
779 return kDifferent; | 736 return kDifferent; |
780 } | 737 } |
781 } | 738 } |
782 | 739 |
783 } // namespace bin | 740 } // namespace bin |
784 } // namespace dart | 741 } // namespace dart |
785 | 742 |
786 #endif // defined(HOST_OS_WINDOWS) | 743 #endif // defined(HOST_OS_WINDOWS) |
OLD | NEW |