Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: runtime/bin/directory_win.cc

Issue 11558012: Use FormatMessageW for Windows error messages to handle internationalized messages correctly. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/bin/file_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/file_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698