Pete Hinchley: Junctions and Symbolic Links

Junction points and symbolic links are features of NTFS that permit file system resources to be accessed via alternate paths.

Junctions are implemented via reparse points (a collection of custom data elements associated with a file or folder). The feature was introduced in NTFS 3.0 (which shipped with Windows 2000). The simplest way to create a junction in Windows Vista, Windows Server 2003, or earlier, is via a utility within the System Internals suite named junction.exe. For example, this command will create a junction point that allows the c:\target directory to be accessed as c:\alias:

junction.exe c:\alias c:\target

A junction point is quite different from a shortcut. A shortcut is a distinct file (with its own unique properties) that links to another file or directory. A junction acts like a pseudonym, and unlike a shortcut, provides transparent access to the target, even via a command prompt.

It is possible to create a junction point in Windows 7, Windows 2008, or later, using the builtin utility mklink. For example, to emulate the previous command:

mklink /J c:\alias c:\target

The mklink utility can also be used to create symbolic links. A symbolic link is similar to a junction, but there are some critical differences. A junction can only point to a location on the local system, whereas a symbolic link can reference a remote network path. For example, you could create a symbolic link from c:\alias to \\remote\c$\target.

Another difference between a junction point and a symbolic link relates to the way they are resolved. A junction is resolved by the system on which it is defined, whereas a symbolic link is resolved at the client. For example, if c:\alias is a junction point to the directory c:\target, when requested via \\remote\c$\alias, access will be granted to the content within c:\target on the remote computer. However, if c:\alias is created as a symbolic link, a request to \\remote\c$\alias will likely result in an error, as the link will be resolved to c:\target on the local computer (which may not exist).

It is possible to list the junction points and symbolic links within a directory by using the following command (the /aL switch asks dir to only display reparse points):

dir /aL

For example, from the c:\users directory on a Windows 8 computer:

26/07/2012  <SYMLINKD>  All Users [C:\ProgramData]
26/07/2012  <DIR>       Default
26/07/2012  <JUNCTION>  Default User [C:\Users\Default]

There are two types of symbolic link: a soft-link and a hard-link. Unlike a junction, which can only access a directory, a hard-link can only access a file, and a soft-link can access either a file or directory. Note: Junctions and hard-links can be created without elevated privileges; soft-links require elevation.

A junction, like a soft-link, is easily differentiated from its target. For example, a soft-link in Windows Explorer is displayed with a shortcut overlay and a zero byte size. A hard-link, and the file from which it was created, are treated as equivalent links to the same content, and cannot be distinguished.

If mklink is run without any switches, it will create a soft-link to a file. For example, the following command will create a new symbolic link named foo.txt that references bar.txt. The file bar.txt does not need to exist prior to running the command, in which case foo.txt will point to an unresolved target.

mklink foo.txt bar.txt

The /D switch can be used to create a soft-link to a directory:

mklink /D c:\temp\alias c:\temp\target

The /H switch can be used to create a hard-link to a file. The command can be executed without elevated privileges, and the target file must already exist (and it must be on the same volume).

mklink /H this.txt that.txt

An interesting aside on hard-links: size and attribute information is only updated on the file through which a change was made. For example, adding content to this.txt will not immediately change the reported size of that.txt. However, upon accessing the properties of that.txt - which can be triggered simply by selecting the file in Explorer - the attribute data is refreshed.

In NTFS, the attributes of a file are stored in an inode. When you create a file, you create an inode, and separate from it, a filename that points to the inode. When you create a hard-link, you are effectively creating another filename pointer to the same inode. The inode maintains a counter of inbound references, and when all filename links are deleted, the inode (and the associated file content) are also purged. Hence, the parent-child relationship that exists with junction points and soft-links does not apply to hard-links. If you delete the target of a junction or a soft-link, the data is lost; however, until you delete all filename references (hard-links) to an inode, the data will persist.