javawindowswinapijna

Determine whether a file is a junction (in Windows) or not?


I've been searching around trying to find a way to determine if a file is a junction or not, and have not found any satisfactory answers.

First thing I tried was:

Files.isSymbolicLink(aPath)

It detects only symbolic links not the files referred to as junctions in Windows.

Also tried the solution proposed here (using JNA library): Stackoverflow question (3249117) , but it never returned true on any of the files I know to be junctions.

The only way I've found to determine which files are junctions is the following command run in windows command prompt:

DIR /S /A:L

On my computer it returns 66 folders, wheras Files.isSymbolicLink(aPath) returned only 2. So I suppose I could find a way to utilize this, but I don't think it would be very effiecient when traversing a filetree.

Is there any way to do this using the standard java library, or alternativly JNA?


Solution

  • If you can write native code in JNA, you can directly call the Win32 API GetFileAttributes() function and check for the FILE_ATTRIBUTE_REPARSE_POINT flag (junctions are implemented as reparse points).

    Update: To differentiate between different types of reparse points, you have to retreive the ReparseTag of the actual reparse point. For a junction point, it will be set to IO_REPARSE_TAG_MOUNT_POINT (0xA0000003).

    There are two ways to retreive the ReparseTag:

    1. Use DeviceIoControl() with the FSCTL_GET_REPARSE_POINT control code to obtain an REPARSE_DATA_BUFFER struct, which as a ReparseTag field. You can see an example of an IsDirectoryJunction() implementation using this technique in the following article:

    NTFS Hard Links, Directory Junctions, and Windows Shortcuts

    1. Use FindFirstFile() to obtain a WIN32_FIND_DATA struct. If the path has the FILE_ATTRIBUTE_REPARSE_POINT attribute, the dwReserved0 field will contain the ReparseTag.