Probably one of the lesser known features of NTFS are reparse points. A reparse point is a virtual path on the file system that points to some other place. If you’re familiar with *nix systems this sounds an awful lot like a symbolic link which is in essence exactly the same thing. Reparse points come in two flavors; junctions and symbolic links. Both allow you to point to some arbitrary path. So what is the difference?
Junctions were one of the first types of reparse points built in to NTFS. They first saw the light of day in Windows 2000. A junction acts much more like a hard link within the file system with the exception that deleting one will not delete the underlying contents. Their limitation is that they can only point to paths on the same or different local volumes on the machine. You cannot for instance make a junction to a network share nor can you make a junction to a file.
Symbolic links on the other hand remove the limitations of junctions and offer the ability to target virtually any arbitrary path. This effectively makes them junctions 2.0 and on par with the *nix counterpart. However, symlinks can only be created with administrative privileges and some parts of the operating system treat them differently whereas junctions are often treated as if they are still a hard link.
Unfortunately Microsoft have made it pretty difficult to work with both. The Windows SDK provides a rather arcane API in the form of DeviceIoControl to work with junctions and the API has a couple of key missing features when working with symbolic links. In addition, the only other available library I could find was severely outdated and doesn’t handle symlinks (see Windows 2000 Junction Points).
So I decided to write a new library. libntfslinks is a modern C++ library for Windows 7/8 that simplifies working with NTFS junctions and symbolic links. The library’s features are:
- Create junctions and symbolic links
- Delete junctions and symbolic links
- Extract the target path of junctions and symbolic links
- Determine if a path is a junction or a symbolic link
- Unicode support
- 32-bit and 64-bit compatible
The library’s API is written to be as simple as possible without any fluff. To create a junction simply call CreateJunction, to check if a path is a symlink use IsSymlink. That’s it!
The code is open source under the BSD license and available on github along with instructions on how to build and use the library.