| Index: runtime/bin/directory_win.cc
|
| diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
|
| index 97a2207fea53461be27be8af97978a38d3ae0475..857739ac872b65b9a019dfa41c439108e10b6f6c 100644
|
| --- a/runtime/bin/directory_win.cc
|
| +++ b/runtime/bin/directory_win.cc
|
| @@ -52,6 +52,7 @@ class PathBuffer {
|
| // Forward declarations.
|
| static bool ListRecursively(PathBuffer* path,
|
| bool recursive,
|
| + bool follow_links,
|
| DirectoryListing* listing);
|
| static bool DeleteRecursively(PathBuffer* path);
|
|
|
| @@ -67,6 +68,7 @@ static void PostError(DirectoryListing* listing,
|
| static bool HandleDir(wchar_t* dir_name,
|
| PathBuffer* path,
|
| bool recursive,
|
| + bool follow_links,
|
| DirectoryListing* listing) {
|
| if (wcscmp(dir_name, L".") == 0) return true;
|
| if (wcscmp(dir_name, L"..") == 0) return true;
|
| @@ -77,7 +79,8 @@ static bool HandleDir(wchar_t* dir_name,
|
| char* utf8_path = StringUtils::WideToUtf8(path->data);
|
| bool ok = listing->HandleDirectory(utf8_path);
|
| free(utf8_path);
|
| - return ok && (!recursive || ListRecursively(path, recursive, listing));
|
| + return ok &&
|
| + (!recursive || ListRecursively(path, recursive, follow_links, listing));
|
| }
|
|
|
|
|
| @@ -95,15 +98,33 @@ static bool HandleFile(wchar_t* file_name,
|
| }
|
|
|
|
|
| +static bool HandleLink(wchar_t* link_name,
|
| + PathBuffer* path,
|
| + DirectoryListing* listing) {
|
| + if (!path->Add(link_name)) {
|
| + PostError(listing, path->data);
|
| + return false;
|
| + }
|
| + char* utf8_path = StringUtils::WideToUtf8(path->data);
|
| + bool ok = listing->HandleLink(utf8_path);
|
| + free(utf8_path);
|
| + return ok;
|
| +}
|
| +
|
| +
|
| static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data,
|
| PathBuffer* path,
|
| bool recursive,
|
| + bool follow_links,
|
| DirectoryListing* listing) {
|
| DWORD attributes = find_file_data->dwFileAttributes;
|
| - if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
| + if (!follow_links && (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
|
| + return HandleLink(find_file_data->cFileName, path, listing);
|
| + } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
| return HandleDir(find_file_data->cFileName,
|
| path,
|
| recursive,
|
| + follow_links,
|
| listing);
|
| } else {
|
| return HandleFile(find_file_data->cFileName, path, listing);
|
| @@ -113,6 +134,7 @@ static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data,
|
|
|
| static bool ListRecursively(PathBuffer* path,
|
| bool recursive,
|
| + bool follow_links,
|
| DirectoryListing* listing) {
|
| if (!path->Add(L"\\*")) {
|
| PostError(listing, path->data);
|
| @@ -134,6 +156,7 @@ static bool ListRecursively(PathBuffer* path,
|
| bool success = HandleEntry(&find_file_data,
|
| path,
|
| recursive,
|
| + follow_links,
|
| listing);
|
|
|
| while ((FindNextFileW(find_handle, &find_file_data) != 0)) {
|
| @@ -141,6 +164,7 @@ static bool ListRecursively(PathBuffer* path,
|
| success = HandleEntry(&find_file_data,
|
| path,
|
| recursive,
|
| + follow_links,
|
| listing) && success;
|
| }
|
|
|
| @@ -250,6 +274,7 @@ static bool DeleteRecursively(PathBuffer* path) {
|
|
|
| bool Directory::List(const char* dir_name,
|
| bool recursive,
|
| + bool follow_links,
|
| DirectoryListing* listing) {
|
| const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name);
|
| PathBuffer path;
|
| @@ -258,7 +283,7 @@ bool Directory::List(const char* dir_name,
|
| return false;
|
| }
|
| free(const_cast<wchar_t*>(system_name));
|
| - return ListRecursively(&path, recursive, listing);
|
| + return ListRecursively(&path, recursive, follow_links, listing);
|
| }
|
|
|
|
|
|
|