Identifying bad ReparsePoints with GetDirectories() in .Net 3.5?

777 views Asked by At

I am using Directory.GetDirectories() with a Linq statement to loop through all directories in a folder that aren't system folders, however I am discovering a bunch of bad ReparsePoints in the folder, which is causing the method to take a long time as it times out on each bad reparse point.

The code I am currently using looks like this:

subdirectories = directory.GetDirectories("*", SearchOption.TopDirectoryOnly)
    .Where(d => ((d.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
         && ((d.Attributes & FileAttributes.System) != FileAttributes.System));

I have also tried using code like this for testing, but it also hangs for a full minute or so on the bad folders:

foreach (var item in dir.GetDirectories("*", SearchOption.TopDirectoryOnly))
{
    Console.WriteLine(item.Name);
    Console.WriteLine(item.Attributes);
}

It should be noted that the above bit of code works fine in .Net 4.0, but in 3.5 it will hang for a minute on each bad reparse point.

Trying to open these folders manually in Windows Explorer results in a "Network Path Not Found" error.

Is there another way to loop through good subfolders inside a folder that doesn't use the Attributes property, or that bypasses the bad reparse points?

I have already tried using Directory.Exists(), and that is equally slow.

1

There are 1 answers

0
sehe On

According to this answer: *FASTEST* directory listing

For the best performance, it is possible to P/Invoke NtQueryDirectoryFile, documented as ZwQueryDirectoryFile

From MSDN: FILE_REPARSE_POINT_INFORMATION structure

This information can be queried in either of the following ways:

Call ZwQueryDirectoryFile, passing FileReparsePointInformation as the value of FileInformationClass and passing a caller-allocated, FILE_REPARSE_POINT_INFORMATION-structured buffer as the value of FileInformation.

Create an IRP with major function code IRP_MJ_DIRECTORY_CONTROL and minor function code IRP_MN_QUERY_DIRECTORY.