| 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 "bin/directory.h" | 5 #include "bin/directory.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 | 9 |
| 10 #include "bin/log.h" | 10 #include "bin/log.h" |
| 11 | 11 |
| 12 static int SetOsErrorMessage(char* os_error_message, | |
| 13 int os_error_message_len) { | |
| 14 int error_code = GetLastError(); | |
| 15 DWORD message_size = | |
| 16 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |
| 17 NULL, | |
| 18 error_code, | |
| 19 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
| 20 os_error_message, | |
| 21 os_error_message_len, | |
| 22 NULL); | |
| 23 if (message_size == 0) { | |
| 24 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | |
| 25 Log::PrintErr("FormatMessage failed %d\n", GetLastError()); | |
| 26 } | |
| 27 snprintf(os_error_message, os_error_message_len, "OS Error %d", error_code); | |
| 28 } | |
| 29 os_error_message[os_error_message_len - 1] = '\0'; | |
| 30 return error_code; | |
| 31 } | |
| 32 | |
| 33 | |
| 34 // Forward declaration. | 12 // Forward declaration. |
| 35 static bool ListRecursively(const char* dir_name, | 13 static bool ListRecursively(const char* dir_name, |
| 36 bool recursive, | 14 bool recursive, |
| 37 DirectoryListing* listing); | 15 DirectoryListing* listing); |
| 38 static bool DeleteRecursively(const char* dir_name); | 16 static bool DeleteRecursively(const char* dir_name); |
| 39 | 17 |
| 40 | 18 |
| 41 static bool HandleDir(char* dir_name, | 19 static bool HandleDir(char* dir_name, |
| 42 char* path, | 20 char* path, |
| 43 int path_length, | 21 int path_length, |
| 44 bool recursive, | 22 bool recursive, |
| 45 DirectoryListing* listing) { | 23 DirectoryListing* listing) { |
| 46 if (strcmp(dir_name, ".") != 0 && | 24 if (strcmp(dir_name, ".") != 0 && |
| 47 strcmp(dir_name, "..") != 0) { | 25 strcmp(dir_name, "..") != 0) { |
| 48 size_t written = snprintf(path + path_length, | 26 size_t written = snprintf(path + path_length, |
| 49 MAX_PATH - path_length, | 27 MAX_PATH - path_length, |
| 50 "%s", | 28 "%s", |
| 51 dir_name); | 29 dir_name); |
| 52 if (written != strlen(dir_name)) { | 30 if (written != strlen(dir_name)) { |
| 53 return false; | 31 return false; |
| 54 } | 32 } |
| 55 char* utf8_path = StringUtils::SystemStringToUtf8(path); | 33 char* utf8_path = StringUtils::ConsoleStringToUtf8(path); |
| 56 bool ok = listing->HandleDirectory(utf8_path); | 34 bool ok = listing->HandleDirectory(utf8_path); |
| 57 free(utf8_path); | 35 free(utf8_path); |
| 58 if (!ok) return ok; | 36 if (!ok) return ok; |
| 59 if (recursive) { | 37 if (recursive) { |
| 60 return ListRecursively(path, recursive, listing); | 38 return ListRecursively(path, recursive, listing); |
| 61 } | 39 } |
| 62 } | 40 } |
| 63 return true; | 41 return true; |
| 64 } | 42 } |
| 65 | 43 |
| 66 | 44 |
| 67 static bool HandleFile(char* file_name, | 45 static bool HandleFile(char* file_name, |
| 68 char* path, | 46 char* path, |
| 69 int path_length, | 47 int path_length, |
| 70 DirectoryListing* listing) { | 48 DirectoryListing* listing) { |
| 71 size_t written = snprintf(path + path_length, | 49 size_t written = snprintf(path + path_length, |
| 72 MAX_PATH - path_length, | 50 MAX_PATH - path_length, |
| 73 "%s", | 51 "%s", |
| 74 file_name); | 52 file_name); |
| 75 if (written != strlen(file_name)) { | 53 if (written != strlen(file_name)) { |
| 76 return false; | 54 return false; |
| 77 }; | 55 }; |
| 78 char* utf8_path = StringUtils::SystemStringToUtf8(path); | 56 char* utf8_path = StringUtils::ConsoleStringToUtf8(path); |
| 79 bool ok = listing->HandleFile(utf8_path); | 57 bool ok = listing->HandleFile(utf8_path); |
| 80 free(utf8_path); | 58 free(utf8_path); |
| 81 return ok; | 59 return ok; |
| 82 } | 60 } |
| 83 | 61 |
| 84 | 62 |
| 85 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, | 63 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, |
| 86 char* path, | 64 char* path, |
| 87 int path_length, | 65 int path_length, |
| 88 bool recursive, | 66 bool recursive, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 "\\*"); | 100 "\\*"); |
| 123 if (written != 2) { | 101 if (written != 2) { |
| 124 return false; | 102 return false; |
| 125 } | 103 } |
| 126 *path_length += written; | 104 *path_length += written; |
| 127 return true; | 105 return true; |
| 128 } | 106 } |
| 129 | 107 |
| 130 static void PostError(DirectoryListing* listing, | 108 static void PostError(DirectoryListing* listing, |
| 131 const char* dir_name) { | 109 const char* dir_name) { |
| 132 const char* utf8_path = StringUtils::SystemStringToUtf8(dir_name); | 110 const char* utf8_path = StringUtils::ConsoleStringToUtf8(dir_name); |
| 133 listing->HandleError(utf8_path); | 111 listing->HandleError(utf8_path); |
| 134 free(const_cast<char*>(utf8_path)); | 112 free(const_cast<char*>(utf8_path)); |
| 135 } | 113 } |
| 136 | 114 |
| 137 | 115 |
| 138 static bool ListRecursively(const char* dir_name, | 116 static bool ListRecursively(const char* dir_name, |
| 139 bool recursive, | 117 bool recursive, |
| 140 DirectoryListing* listing) { | 118 DirectoryListing* listing) { |
| 141 // Compute full path for the directory currently being listed. The | 119 // Compute full path for the directory currently being listed. The |
| 142 // path buffer will be used to construct the current path in the | 120 // path buffer will be used to construct the current path in the |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 return false; | 291 return false; |
| 314 } | 292 } |
| 315 | 293 |
| 316 return success; | 294 return success; |
| 317 } | 295 } |
| 318 | 296 |
| 319 | 297 |
| 320 bool Directory::List(const char* dir_name, | 298 bool Directory::List(const char* dir_name, |
| 321 bool recursive, | 299 bool recursive, |
| 322 DirectoryListing* listing) { | 300 DirectoryListing* listing) { |
| 323 const char* system_name = StringUtils::Utf8ToSystemString(dir_name); | 301 const char* system_name = StringUtils::Utf8ToConsoleString(dir_name); |
| 324 bool completed = ListRecursively(system_name, recursive, listing); | 302 bool completed = ListRecursively(system_name, recursive, listing); |
| 325 free(const_cast<char*>(system_name)); | 303 free(const_cast<char*>(system_name)); |
| 326 return completed; | 304 return completed; |
| 327 } | 305 } |
| 328 | 306 |
| 329 | 307 |
| 330 static Directory::ExistsResult ExistsHelper(const char* dir_name) { | 308 static Directory::ExistsResult ExistsHelper(const char* dir_name) { |
| 331 DWORD attributes = GetFileAttributes(dir_name); | 309 DWORD attributes = GetFileAttributes(dir_name); |
| 332 if (attributes == INVALID_FILE_ATTRIBUTES) { | 310 if (attributes == INVALID_FILE_ATTRIBUTES) { |
| 333 DWORD last_error = GetLastError(); | 311 DWORD last_error = GetLastError(); |
| 334 if (last_error == ERROR_FILE_NOT_FOUND || | 312 if (last_error == ERROR_FILE_NOT_FOUND || |
| 335 last_error == ERROR_PATH_NOT_FOUND) { | 313 last_error == ERROR_PATH_NOT_FOUND) { |
| 336 return Directory::DOES_NOT_EXIST; | 314 return Directory::DOES_NOT_EXIST; |
| 337 } else { | 315 } else { |
| 338 // We might not be able to get the file attributes for other | 316 // We might not be able to get the file attributes for other |
| 339 // reasons such as lack of permissions. In that case we do | 317 // reasons such as lack of permissions. In that case we do |
| 340 // not know if the directory exists. | 318 // not know if the directory exists. |
| 341 return Directory::UNKNOWN; | 319 return Directory::UNKNOWN; |
| 342 } | 320 } |
| 343 } | 321 } |
| 344 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | 322 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |
| 345 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; | 323 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; |
| 346 } | 324 } |
| 347 | 325 |
| 348 | 326 |
| 349 Directory::ExistsResult Directory::Exists(const char* dir_name) { | 327 Directory::ExistsResult Directory::Exists(const char* dir_name) { |
| 350 const char* system_name = StringUtils::Utf8ToSystemString(dir_name); | 328 const char* system_name = StringUtils::Utf8ToConsoleString(dir_name); |
| 351 Directory::ExistsResult result = ExistsHelper(system_name); | 329 Directory::ExistsResult result = ExistsHelper(system_name); |
| 352 free(const_cast<char*>(system_name)); | 330 free(const_cast<char*>(system_name)); |
| 353 return result; | 331 return result; |
| 354 } | 332 } |
| 355 | 333 |
| 356 | 334 |
| 357 char* Directory::Current() { | 335 char* Directory::Current() { |
| 358 int length = GetCurrentDirectory(0, NULL); | 336 int length = GetCurrentDirectory(0, NULL); |
| 359 char* current = reinterpret_cast<char*>(malloc(length + 1)); | 337 char* current = reinterpret_cast<char*>(malloc(length + 1)); |
| 360 GetCurrentDirectory(length + 1, current); | 338 GetCurrentDirectory(length + 1, current); |
| 361 char* result = StringUtils::SystemStringToUtf8(current); | 339 char* result = StringUtils::ConsoleStringToUtf8(current); |
| 362 free(current); | 340 free(current); |
| 363 return result; | 341 return result; |
| 364 } | 342 } |
| 365 | 343 |
| 366 | 344 |
| 367 bool Directory::Create(const char* dir_name) { | 345 bool Directory::Create(const char* dir_name) { |
| 368 const char* system_name = StringUtils::Utf8ToSystemString(dir_name); | 346 const char* system_name = StringUtils::Utf8ToConsoleString(dir_name); |
| 369 // If the directory already exists and is a directory do not | 347 // If the directory already exists and is a directory do not |
| 370 // attempt to create it again and treat it as a success. | 348 // attempt to create it again and treat it as a success. |
| 371 if (ExistsHelper(system_name) == EXISTS) { | 349 if (ExistsHelper(system_name) == EXISTS) { |
| 372 free(const_cast<char*>(system_name)); | 350 free(const_cast<char*>(system_name)); |
| 373 return true; | 351 return true; |
| 374 } | 352 } |
| 375 int create_status = CreateDirectory(system_name, NULL); | 353 int create_status = CreateDirectory(system_name, NULL); |
| 376 free(const_cast<char*>(system_name)); | 354 free(const_cast<char*>(system_name)); |
| 377 return (create_status != 0); | 355 return (create_status != 0); |
| 378 } | 356 } |
| 379 | 357 |
| 380 | 358 |
| 381 char* Directory::CreateTemp(const char* const_template) { | 359 char* Directory::CreateTemp(const char* const_template) { |
| 382 // Returns a new, unused directory name, modifying the contents of | 360 // Returns a new, unused directory name, modifying the contents of |
| 383 // dir_template. Creates this directory, with a default security | 361 // dir_template. Creates this directory, with a default security |
| 384 // descriptor inherited from its parent directory. | 362 // descriptor inherited from its parent directory. |
| 385 // The return value must be freed by the caller. | 363 // The return value must be freed by the caller. |
| 386 char* path = static_cast<char*>(malloc(MAX_PATH)); | 364 char* path = static_cast<char*>(malloc(MAX_PATH)); |
| 387 int path_length; | 365 int path_length; |
| 388 if (0 == strncmp(const_template, "", 1)) { | 366 if (0 == strncmp(const_template, "", 1)) { |
| 389 path_length = GetTempPath(MAX_PATH, path); | 367 path_length = GetTempPath(MAX_PATH, path); |
| 390 if (path_length == 0) { | 368 if (path_length == 0) { |
| 391 free(path); | 369 free(path); |
| 392 return NULL; | 370 return NULL; |
| 393 } | 371 } |
| 394 } else { | 372 } else { |
| 395 const char* system_template = | 373 const char* system_template = |
| 396 StringUtils::Utf8ToSystemString(const_template); | 374 StringUtils::Utf8ToConsoleString(const_template); |
| 397 snprintf(path, MAX_PATH, "%s", system_template); | 375 snprintf(path, MAX_PATH, "%s", system_template); |
| 398 free(const_cast<char*>(system_template)); | 376 free(const_cast<char*>(system_template)); |
| 399 path_length = strlen(path); | 377 path_length = strlen(path); |
| 400 } | 378 } |
| 401 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44. | 379 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44. |
| 402 if (path_length > MAX_PATH - 44) { | 380 if (path_length > MAX_PATH - 44) { |
| 403 free(path); | 381 free(path); |
| 404 return NULL; | 382 return NULL; |
| 405 } | 383 } |
| 406 if ((path)[path_length - 1] == '\\') { | 384 if ((path)[path_length - 1] == '\\') { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 420 if (status != RPC_S_OK) { | 398 if (status != RPC_S_OK) { |
| 421 free(path); | 399 free(path); |
| 422 return NULL; | 400 return NULL; |
| 423 } | 401 } |
| 424 | 402 |
| 425 snprintf(path + path_length, MAX_PATH - path_length, "-%s", uuid_string); | 403 snprintf(path + path_length, MAX_PATH - path_length, "-%s", uuid_string); |
| 426 if (!CreateDirectory(path, NULL)) { | 404 if (!CreateDirectory(path, NULL)) { |
| 427 free(path); | 405 free(path); |
| 428 return NULL; | 406 return NULL; |
| 429 } | 407 } |
| 430 char* result = StringUtils::SystemStringToUtf8(path); | 408 char* result = StringUtils::ConsoleStringToUtf8(path); |
| 431 free(path); | 409 free(path); |
| 432 return result; | 410 return result; |
| 433 } | 411 } |
| 434 | 412 |
| 435 | 413 |
| 436 bool Directory::Delete(const char* dir_name, bool recursive) { | 414 bool Directory::Delete(const char* dir_name, bool recursive) { |
| 437 bool result = false; | 415 bool result = false; |
| 438 const char* system_dir_name = | 416 const char* system_dir_name = |
| 439 StringUtils::Utf8ToSystemString(dir_name); | 417 StringUtils::Utf8ToConsoleString(dir_name); |
| 440 if (!recursive) { | 418 if (!recursive) { |
| 441 result = (RemoveDirectory(system_dir_name) != 0); | 419 result = (RemoveDirectory(system_dir_name) != 0); |
| 442 } else { | 420 } else { |
| 443 result = DeleteRecursively(system_dir_name); | 421 result = DeleteRecursively(system_dir_name); |
| 444 } | 422 } |
| 445 free(const_cast<char*>(system_dir_name)); | 423 free(const_cast<char*>(system_dir_name)); |
| 446 return result; | 424 return result; |
| 447 } | 425 } |
| 448 | 426 |
| 449 | 427 |
| 450 bool Directory::Rename(const char* path, const char* new_path) { | 428 bool Directory::Rename(const char* path, const char* new_path) { |
| 451 const char* system_path = StringUtils::Utf8ToSystemString(path); | 429 const char* system_path = StringUtils::Utf8ToConsoleString(path); |
| 452 const char* system_new_path = | 430 const char* system_new_path = |
| 453 StringUtils::Utf8ToSystemString(new_path); | 431 StringUtils::Utf8ToConsoleString(new_path); |
| 454 ExistsResult exists = ExistsHelper(system_path); | 432 ExistsResult exists = ExistsHelper(system_path); |
| 455 if (exists != EXISTS) return false; | 433 if (exists != EXISTS) return false; |
| 456 ExistsResult new_exists = ExistsHelper(system_new_path); | 434 ExistsResult new_exists = ExistsHelper(system_new_path); |
| 457 // MoveFile does not allow replacing exising directories. Therefore, | 435 // MoveFile does not allow replacing exising directories. Therefore, |
| 458 // if the new_path is currently a directory we need to delete it | 436 // if the new_path is currently a directory we need to delete it |
| 459 // first. | 437 // first. |
| 460 if (new_exists == EXISTS) { | 438 if (new_exists == EXISTS) { |
| 461 bool success = DeleteRecursively(system_new_path); | 439 bool success = DeleteRecursively(system_new_path); |
| 462 if (!success) return false; | 440 if (!success) return false; |
| 463 } | 441 } |
| 464 DWORD flags = MOVEFILE_WRITE_THROUGH; | 442 DWORD flags = MOVEFILE_WRITE_THROUGH; |
| 465 int move_status = | 443 int move_status = |
| 466 MoveFileEx(system_path, system_new_path, flags); | 444 MoveFileEx(system_path, system_new_path, flags); |
| 467 free(const_cast<char*>(system_path)); | 445 free(const_cast<char*>(system_path)); |
| 468 free(const_cast<char*>(system_new_path)); | 446 free(const_cast<char*>(system_new_path)); |
| 469 return (move_status != 0); | 447 return (move_status != 0); |
| 470 } | 448 } |
| OLD | NEW |