| 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/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 { |
| 24 namespace bin { | 24 namespace bin { |
| 25 | 25 |
| 26 PathBuffer::PathBuffer() : length_(0) { | 26 PathBuffer::PathBuffer() : length_(0) { |
| 27 data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT | 27 data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT |
| 28 } | 28 } |
| 29 | 29 |
| 30 | |
| 31 PathBuffer::~PathBuffer() { | 30 PathBuffer::~PathBuffer() { |
| 32 free(data_); | 31 free(data_); |
| 33 } | 32 } |
| 34 | 33 |
| 35 | |
| 36 char* PathBuffer::AsString() const { | 34 char* PathBuffer::AsString() const { |
| 37 UNREACHABLE(); | 35 UNREACHABLE(); |
| 38 return NULL; | 36 return NULL; |
| 39 } | 37 } |
| 40 | 38 |
| 41 | |
| 42 wchar_t* PathBuffer::AsStringW() const { | 39 wchar_t* PathBuffer::AsStringW() const { |
| 43 return reinterpret_cast<wchar_t*>(data_); | 40 return reinterpret_cast<wchar_t*>(data_); |
| 44 } | 41 } |
| 45 | 42 |
| 46 | |
| 47 const char* PathBuffer::AsScopedString() const { | 43 const char* PathBuffer::AsScopedString() const { |
| 48 return StringUtilsWin::WideToUtf8(AsStringW()); | 44 return StringUtilsWin::WideToUtf8(AsStringW()); |
| 49 } | 45 } |
| 50 | 46 |
| 51 | |
| 52 bool PathBuffer::Add(const char* name) { | 47 bool PathBuffer::Add(const char* name) { |
| 53 Utf8ToWideScope wide_name(name); | 48 Utf8ToWideScope wide_name(name); |
| 54 return AddW(wide_name.wide()); | 49 return AddW(wide_name.wide()); |
| 55 } | 50 } |
| 56 | 51 |
| 57 | |
| 58 bool PathBuffer::AddW(const wchar_t* name) { | 52 bool PathBuffer::AddW(const wchar_t* name) { |
| 59 wchar_t* data = AsStringW(); | 53 wchar_t* data = AsStringW(); |
| 60 int written = | 54 int written = |
| 61 _snwprintf(data + length_, MAX_LONG_PATH - length_, L"%s", name); | 55 _snwprintf(data + length_, MAX_LONG_PATH - length_, L"%s", name); |
| 62 data[MAX_LONG_PATH] = L'\0'; | 56 data[MAX_LONG_PATH] = L'\0'; |
| 63 if ((written <= MAX_LONG_PATH - length_) && (written >= 0) && | 57 if ((written <= MAX_LONG_PATH - length_) && (written >= 0) && |
| 64 (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) { | 58 (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) { |
| 65 length_ += written; | 59 length_ += written; |
| 66 return true; | 60 return true; |
| 67 } else { | 61 } else { |
| 68 SetLastError(ERROR_BUFFER_OVERFLOW); | 62 SetLastError(ERROR_BUFFER_OVERFLOW); |
| 69 return false; | 63 return false; |
| 70 } | 64 } |
| 71 } | 65 } |
| 72 | 66 |
| 73 | |
| 74 void PathBuffer::Reset(intptr_t new_length) { | 67 void PathBuffer::Reset(intptr_t new_length) { |
| 75 length_ = new_length; | 68 length_ = new_length; |
| 76 AsStringW()[length_] = L'\0'; | 69 AsStringW()[length_] = L'\0'; |
| 77 } | 70 } |
| 78 | 71 |
| 79 | |
| 80 // If link_name points to a link, IsBrokenLink will return true if link_name | 72 // If link_name points to a link, IsBrokenLink will return true if link_name |
| 81 // points to an invalid target. | 73 // points to an invalid target. |
| 82 static bool IsBrokenLink(const wchar_t* link_name) { | 74 static bool IsBrokenLink(const wchar_t* link_name) { |
| 83 HANDLE handle = CreateFileW( | 75 HANDLE handle = CreateFileW( |
| 84 link_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | 76 link_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 85 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | 77 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| 86 if (handle == INVALID_HANDLE_VALUE) { | 78 if (handle == INVALID_HANDLE_VALUE) { |
| 87 return true; | 79 return true; |
| 88 } else { | 80 } else { |
| 89 CloseHandle(handle); | 81 CloseHandle(handle); |
| 90 return false; | 82 return false; |
| 91 } | 83 } |
| 92 } | 84 } |
| 93 | 85 |
| 94 | |
| 95 // A linked list structure holding a link target's unique file system ID. | 86 // A linked list structure holding a link target's unique file system ID. |
| 96 // Used to detect loops in the file system when listing recursively. | 87 // Used to detect loops in the file system when listing recursively. |
| 97 struct LinkList { | 88 struct LinkList { |
| 98 DWORD volume; | 89 DWORD volume; |
| 99 DWORD id_low; | 90 DWORD id_low; |
| 100 DWORD id_high; | 91 DWORD id_high; |
| 101 LinkList* next; | 92 LinkList* next; |
| 102 }; | 93 }; |
| 103 | 94 |
| 104 // Forward declarations. | 95 // Forward declarations. |
| 105 static bool DeleteRecursively(PathBuffer* path); | 96 static bool DeleteRecursively(PathBuffer* path); |
| 106 | 97 |
| 107 | |
| 108 static ListType HandleFindFile(DirectoryListing* listing, | 98 static ListType HandleFindFile(DirectoryListing* listing, |
| 109 DirectoryListingEntry* entry, | 99 DirectoryListingEntry* entry, |
| 110 const WIN32_FIND_DATAW& find_file_data) { | 100 const WIN32_FIND_DATAW& find_file_data) { |
| 111 if (!listing->path_buffer().AddW(find_file_data.cFileName)) { | 101 if (!listing->path_buffer().AddW(find_file_data.cFileName)) { |
| 112 return kListError; | 102 return kListError; |
| 113 } | 103 } |
| 114 DWORD attributes = find_file_data.dwFileAttributes; | 104 DWORD attributes = find_file_data.dwFileAttributes; |
| 115 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 105 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 116 if (!listing->follow_links()) { | 106 if (!listing->follow_links()) { |
| 117 return kListLink; | 107 return kListLink; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 if ((wcscmp(find_file_data.cFileName, L".") == 0) || | 153 if ((wcscmp(find_file_data.cFileName, L".") == 0) || |
| 164 (wcscmp(find_file_data.cFileName, L"..") == 0)) { | 154 (wcscmp(find_file_data.cFileName, L"..") == 0)) { |
| 165 return entry->Next(listing); | 155 return entry->Next(listing); |
| 166 } | 156 } |
| 167 return kListDirectory; | 157 return kListDirectory; |
| 168 } else { | 158 } else { |
| 169 return kListFile; | 159 return kListFile; |
| 170 } | 160 } |
| 171 } | 161 } |
| 172 | 162 |
| 173 | |
| 174 ListType DirectoryListingEntry::Next(DirectoryListing* listing) { | 163 ListType DirectoryListingEntry::Next(DirectoryListing* listing) { |
| 175 if (done_) { | 164 if (done_) { |
| 176 return kListDone; | 165 return kListDone; |
| 177 } | 166 } |
| 178 | 167 |
| 179 WIN32_FIND_DATAW find_file_data; | 168 WIN32_FIND_DATAW find_file_data; |
| 180 | 169 |
| 181 if (lister_ == 0) { | 170 if (lister_ == 0) { |
| 182 const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*"; | 171 const wchar_t* tail = parent_ == NULL ? L"*" : L"\\*"; |
| 183 if (!listing->path_buffer().AddW(tail)) { | 172 if (!listing->path_buffer().AddW(tail)) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 212 | 201 |
| 213 done_ = true; | 202 done_ = true; |
| 214 | 203 |
| 215 if (GetLastError() != ERROR_NO_MORE_FILES) { | 204 if (GetLastError() != ERROR_NO_MORE_FILES) { |
| 216 return kListError; | 205 return kListError; |
| 217 } | 206 } |
| 218 | 207 |
| 219 return kListDone; | 208 return kListDone; |
| 220 } | 209 } |
| 221 | 210 |
| 222 | |
| 223 DirectoryListingEntry::~DirectoryListingEntry() { | 211 DirectoryListingEntry::~DirectoryListingEntry() { |
| 224 ResetLink(); | 212 ResetLink(); |
| 225 if (lister_ != 0) { | 213 if (lister_ != 0) { |
| 226 FindClose(reinterpret_cast<HANDLE>(lister_)); | 214 FindClose(reinterpret_cast<HANDLE>(lister_)); |
| 227 } | 215 } |
| 228 } | 216 } |
| 229 | 217 |
| 230 | |
| 231 void DirectoryListingEntry::ResetLink() { | 218 void DirectoryListingEntry::ResetLink() { |
| 232 if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) { | 219 if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) { |
| 233 delete link_; | 220 delete link_; |
| 234 link_ = NULL; | 221 link_ = NULL; |
| 235 } | 222 } |
| 236 if (parent_ != NULL) { | 223 if (parent_ != NULL) { |
| 237 link_ = parent_->link_; | 224 link_ = parent_->link_; |
| 238 } | 225 } |
| 239 } | 226 } |
| 240 | 227 |
| 241 | |
| 242 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) { | 228 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) { |
| 243 if (!path->AddW(file_name)) { | 229 if (!path->AddW(file_name)) { |
| 244 return false; | 230 return false; |
| 245 } | 231 } |
| 246 | 232 |
| 247 if (DeleteFileW(path->AsStringW()) != 0) { | 233 if (DeleteFileW(path->AsStringW()) != 0) { |
| 248 return true; | 234 return true; |
| 249 } | 235 } |
| 250 | 236 |
| 251 // If we failed because the file is read-only, make it writeable and try | 237 // If we failed because the file is read-only, make it writeable and try |
| (...skipping 12 matching lines...) Expand all Loading... |
| 264 return false; | 250 return false; |
| 265 } | 251 } |
| 266 | 252 |
| 267 return DeleteFileW(path->AsStringW()) != 0; | 253 return DeleteFileW(path->AsStringW()) != 0; |
| 268 } | 254 } |
| 269 } | 255 } |
| 270 | 256 |
| 271 return false; | 257 return false; |
| 272 } | 258 } |
| 273 | 259 |
| 274 | |
| 275 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { | 260 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { |
| 276 if ((wcscmp(dir_name, L".") == 0) || (wcscmp(dir_name, L"..") == 0)) { | 261 if ((wcscmp(dir_name, L".") == 0) || (wcscmp(dir_name, L"..") == 0)) { |
| 277 return true; | 262 return true; |
| 278 } | 263 } |
| 279 return path->AddW(dir_name) && DeleteRecursively(path); | 264 return path->AddW(dir_name) && DeleteRecursively(path); |
| 280 } | 265 } |
| 281 | 266 |
| 282 | |
| 283 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { | 267 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { |
| 284 DWORD attributes = find_file_data->dwFileAttributes; | 268 DWORD attributes = find_file_data->dwFileAttributes; |
| 285 | 269 |
| 286 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 270 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
| 287 return DeleteDir(find_file_data->cFileName, path); | 271 return DeleteDir(find_file_data->cFileName, path); |
| 288 } else { | 272 } else { |
| 289 return DeleteFile(find_file_data->cFileName, path); | 273 return DeleteFile(find_file_data->cFileName, path); |
| 290 } | 274 } |
| 291 } | 275 } |
| 292 | 276 |
| 293 | |
| 294 static bool DeleteRecursively(PathBuffer* path) { | 277 static bool DeleteRecursively(PathBuffer* path) { |
| 295 DWORD attributes = GetFileAttributesW(path->AsStringW()); | 278 DWORD attributes = GetFileAttributesW(path->AsStringW()); |
| 296 if (attributes == INVALID_FILE_ATTRIBUTES) { | 279 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 297 return false; | 280 return false; |
| 298 } | 281 } |
| 299 // If the directory is a junction, it's pointing to some other place in the | 282 // If the directory is a junction, it's pointing to some other place in the |
| 300 // filesystem that we do not want to recurse into. | 283 // filesystem that we do not want to recurse into. |
| 301 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 284 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 302 // Just delete the junction itself. | 285 // Just delete the junction itself. |
| 303 return RemoveDirectoryW(path->AsStringW()) != 0; | 286 return RemoveDirectoryW(path->AsStringW()) != 0; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 if (last_error != ERROR_NO_MORE_FILES) { | 318 if (last_error != ERROR_NO_MORE_FILES) { |
| 336 // Unexpected error, set and return. | 319 // Unexpected error, set and return. |
| 337 SetLastError(last_error); | 320 SetLastError(last_error); |
| 338 return false; | 321 return false; |
| 339 } | 322 } |
| 340 // All content deleted succesfully, try to delete directory. | 323 // All content deleted succesfully, try to delete directory. |
| 341 path->Reset(path_length - 1); // Drop the "\" from the end of the path. | 324 path->Reset(path_length - 1); // Drop the "\" from the end of the path. |
| 342 return RemoveDirectoryW(path->AsStringW()) != 0; | 325 return RemoveDirectoryW(path->AsStringW()) != 0; |
| 343 } | 326 } |
| 344 | 327 |
| 345 | |
| 346 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { | 328 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { |
| 347 DWORD attributes = GetFileAttributesW(dir_name); | 329 DWORD attributes = GetFileAttributesW(dir_name); |
| 348 if (attributes == INVALID_FILE_ATTRIBUTES) { | 330 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 349 DWORD last_error = GetLastError(); | 331 DWORD last_error = GetLastError(); |
| 350 if ((last_error == ERROR_FILE_NOT_FOUND) || | 332 if ((last_error == ERROR_FILE_NOT_FOUND) || |
| 351 (last_error == ERROR_PATH_NOT_FOUND)) { | 333 (last_error == ERROR_PATH_NOT_FOUND)) { |
| 352 return Directory::DOES_NOT_EXIST; | 334 return Directory::DOES_NOT_EXIST; |
| 353 } else { | 335 } else { |
| 354 // We might not be able to get the file attributes for other | 336 // We might not be able to get the file attributes for other |
| 355 // reasons such as lack of permissions. In that case we do | 337 // reasons such as lack of permissions. In that case we do |
| 356 // not know if the directory exists. | 338 // not know if the directory exists. |
| 357 return Directory::UNKNOWN; | 339 return Directory::UNKNOWN; |
| 358 } | 340 } |
| 359 } | 341 } |
| 360 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | 342 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
| 361 exists = exists && !IsBrokenLink(dir_name); | 343 exists = exists && !IsBrokenLink(dir_name); |
| 362 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; | 344 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; |
| 363 } | 345 } |
| 364 | 346 |
| 365 | |
| 366 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 347 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
| 367 Utf8ToWideScope system_name(dir_name); | 348 Utf8ToWideScope system_name(dir_name); |
| 368 return ExistsHelper(system_name.wide()); | 349 return ExistsHelper(system_name.wide()); |
| 369 } | 350 } |
| 370 | 351 |
| 371 | |
| 372 char* Directory::CurrentNoScope() { | 352 char* Directory::CurrentNoScope() { |
| 373 int length = GetCurrentDirectoryW(0, NULL); | 353 int length = GetCurrentDirectoryW(0, NULL); |
| 374 if (length == 0) { | 354 if (length == 0) { |
| 375 return NULL; | 355 return NULL; |
| 376 } | 356 } |
| 377 wchar_t* current = new wchar_t[length + 1]; | 357 wchar_t* current = new wchar_t[length + 1]; |
| 378 GetCurrentDirectoryW(length + 1, current); | 358 GetCurrentDirectoryW(length + 1, current); |
| 379 int utf8_len = | 359 int utf8_len = |
| 380 WideCharToMultiByte(CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL); | 360 WideCharToMultiByte(CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL); |
| 381 char* result = reinterpret_cast<char*>(malloc(utf8_len)); | 361 char* result = reinterpret_cast<char*>(malloc(utf8_len)); |
| 382 WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL); | 362 WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL); |
| 383 delete[] current; | 363 delete[] current; |
| 384 return result; | 364 return result; |
| 385 } | 365 } |
| 386 | 366 |
| 387 | |
| 388 const char* Directory::Current() { | 367 const char* Directory::Current() { |
| 389 int length = GetCurrentDirectoryW(0, NULL); | 368 int length = GetCurrentDirectoryW(0, NULL); |
| 390 if (length == 0) { | 369 if (length == 0) { |
| 391 return NULL; | 370 return NULL; |
| 392 } | 371 } |
| 393 wchar_t* current; | 372 wchar_t* current; |
| 394 current = reinterpret_cast<wchar_t*>( | 373 current = reinterpret_cast<wchar_t*>( |
| 395 Dart_ScopeAllocate((length + 1) * sizeof(*current))); | 374 Dart_ScopeAllocate((length + 1) * sizeof(*current))); |
| 396 GetCurrentDirectoryW(length + 1, current); | 375 GetCurrentDirectoryW(length + 1, current); |
| 397 return StringUtilsWin::WideToUtf8(current); | 376 return StringUtilsWin::WideToUtf8(current); |
| 398 } | 377 } |
| 399 | 378 |
| 400 | |
| 401 bool Directory::SetCurrent(const char* path) { | 379 bool Directory::SetCurrent(const char* path) { |
| 402 Utf8ToWideScope system_path(path); | 380 Utf8ToWideScope system_path(path); |
| 403 bool result = SetCurrentDirectoryW(system_path.wide()) != 0; | 381 bool result = SetCurrentDirectoryW(system_path.wide()) != 0; |
| 404 return result; | 382 return result; |
| 405 } | 383 } |
| 406 | 384 |
| 407 | |
| 408 bool Directory::Create(const char* dir_name) { | 385 bool Directory::Create(const char* dir_name) { |
| 409 Utf8ToWideScope system_name(dir_name); | 386 Utf8ToWideScope system_name(dir_name); |
| 410 int create_status = CreateDirectoryW(system_name.wide(), NULL); | 387 int create_status = CreateDirectoryW(system_name.wide(), NULL); |
| 411 // If the directory already existed, treat it as a success. | 388 // If the directory already existed, treat it as a success. |
| 412 if ((create_status == 0) && (GetLastError() == ERROR_ALREADY_EXISTS) && | 389 if ((create_status == 0) && (GetLastError() == ERROR_ALREADY_EXISTS) && |
| 413 (ExistsHelper(system_name.wide()) == EXISTS)) { | 390 (ExistsHelper(system_name.wide()) == EXISTS)) { |
| 414 return true; | 391 return true; |
| 415 } | 392 } |
| 416 return (create_status != 0); | 393 return (create_status != 0); |
| 417 } | 394 } |
| 418 | 395 |
| 419 | |
| 420 const char* Directory::SystemTemp() { | 396 const char* Directory::SystemTemp() { |
| 421 PathBuffer path; | 397 PathBuffer path; |
| 422 // Remove \ at end. | 398 // Remove \ at end. |
| 423 path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1); | 399 path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1); |
| 424 return path.AsScopedString(); | 400 return path.AsScopedString(); |
| 425 } | 401 } |
| 426 | 402 |
| 427 | |
| 428 const char* Directory::CreateTemp(const char* prefix) { | 403 const char* Directory::CreateTemp(const char* prefix) { |
| 429 // Returns a new, unused directory name, adding characters to the | 404 // Returns a new, unused directory name, adding characters to the |
| 430 // end of prefix. | 405 // end of prefix. |
| 431 // Creates this directory, with a default security | 406 // Creates this directory, with a default security |
| 432 // descriptor inherited from its parent directory. | 407 // descriptor inherited from its parent directory. |
| 433 // The return value is Dart_ScopeAllocated. | 408 // The return value is Dart_ScopeAllocated. |
| 434 PathBuffer path; | 409 PathBuffer path; |
| 435 Utf8ToWideScope system_prefix(prefix); | 410 Utf8ToWideScope system_prefix(prefix); |
| 436 if (!path.AddW(system_prefix.wide())) { | 411 if (!path.AddW(system_prefix.wide())) { |
| 437 return NULL; | 412 return NULL; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 457 if (!path.AddW(reinterpret_cast<wchar_t*>(uuid_string))) { | 432 if (!path.AddW(reinterpret_cast<wchar_t*>(uuid_string))) { |
| 458 return NULL; | 433 return NULL; |
| 459 } | 434 } |
| 460 RpcStringFreeW(&uuid_string); | 435 RpcStringFreeW(&uuid_string); |
| 461 if (!CreateDirectoryW(path.AsStringW(), NULL)) { | 436 if (!CreateDirectoryW(path.AsStringW(), NULL)) { |
| 462 return NULL; | 437 return NULL; |
| 463 } | 438 } |
| 464 return path.AsScopedString(); | 439 return path.AsScopedString(); |
| 465 } | 440 } |
| 466 | 441 |
| 467 | |
| 468 bool Directory::Delete(const char* dir_name, bool recursive) { | 442 bool Directory::Delete(const char* dir_name, bool recursive) { |
| 469 bool result = false; | 443 bool result = false; |
| 470 Utf8ToWideScope system_dir_name(dir_name); | 444 Utf8ToWideScope system_dir_name(dir_name); |
| 471 if (!recursive) { | 445 if (!recursive) { |
| 472 if (File::GetType(dir_name, true) == File::kIsDirectory) { | 446 if (File::GetType(dir_name, true) == File::kIsDirectory) { |
| 473 result = (RemoveDirectoryW(system_dir_name.wide()) != 0); | 447 result = (RemoveDirectoryW(system_dir_name.wide()) != 0); |
| 474 } else { | 448 } else { |
| 475 SetLastError(ERROR_FILE_NOT_FOUND); | 449 SetLastError(ERROR_FILE_NOT_FOUND); |
| 476 } | 450 } |
| 477 } else { | 451 } else { |
| 478 PathBuffer path; | 452 PathBuffer path; |
| 479 if (path.AddW(system_dir_name.wide())) { | 453 if (path.AddW(system_dir_name.wide())) { |
| 480 result = DeleteRecursively(&path); | 454 result = DeleteRecursively(&path); |
| 481 } | 455 } |
| 482 } | 456 } |
| 483 return result; | 457 return result; |
| 484 } | 458 } |
| 485 | 459 |
| 486 | |
| 487 bool Directory::Rename(const char* path, const char* new_path) { | 460 bool Directory::Rename(const char* path, const char* new_path) { |
| 488 Utf8ToWideScope system_path(path); | 461 Utf8ToWideScope system_path(path); |
| 489 Utf8ToWideScope system_new_path(new_path); | 462 Utf8ToWideScope system_new_path(new_path); |
| 490 ExistsResult exists = ExistsHelper(system_path.wide()); | 463 ExistsResult exists = ExistsHelper(system_path.wide()); |
| 491 if (exists != EXISTS) { | 464 if (exists != EXISTS) { |
| 492 return false; | 465 return false; |
| 493 } | 466 } |
| 494 ExistsResult new_exists = ExistsHelper(system_new_path.wide()); | 467 ExistsResult new_exists = ExistsHelper(system_new_path.wide()); |
| 495 // MoveFile does not allow replacing existing directories. Therefore, | 468 // MoveFile does not allow replacing existing directories. Therefore, |
| 496 // if the new_path is currently a directory we need to delete it | 469 // if the new_path is currently a directory we need to delete it |
| 497 // first. | 470 // first. |
| 498 if (new_exists == EXISTS) { | 471 if (new_exists == EXISTS) { |
| 499 bool success = Delete(new_path, true); | 472 bool success = Delete(new_path, true); |
| 500 if (!success) { | 473 if (!success) { |
| 501 return false; | 474 return false; |
| 502 } | 475 } |
| 503 } | 476 } |
| 504 DWORD flags = MOVEFILE_WRITE_THROUGH; | 477 DWORD flags = MOVEFILE_WRITE_THROUGH; |
| 505 int move_status = | 478 int move_status = |
| 506 MoveFileExW(system_path.wide(), system_new_path.wide(), flags); | 479 MoveFileExW(system_path.wide(), system_new_path.wide(), flags); |
| 507 return (move_status != 0); | 480 return (move_status != 0); |
| 508 } | 481 } |
| 509 | 482 |
| 510 } // namespace bin | 483 } // namespace bin |
| 511 } // namespace dart | 484 } // namespace dart |
| 512 | 485 |
| 513 #endif // defined(HOST_OS_WINDOWS) | 486 #endif // defined(HOST_OS_WINDOWS) |
| OLD | NEW |