Windows symlinks

Windows_LogoA few days ago, while going out with the team, celebrating a release of the project we’re working on, we started discussing not about skirts lengths and the wonderful summer-y feel of the evening, not even about how many bottles of beer one can indulge themselves into, but about linking files. It happens with programmers that these kind of discussions tend to become the most dangerous, although apparently innocuous. Things like your favorite editor, browser or TAB size tend to become quite important; so it’s no surprise that linking files can become a very heated topic. For me, it was learning time.

The problem: Windows doesn’t support linking. Linking is very useful, and it’s there since the mother of all decent operating systems, UNIX. Linking is extremely useful, especially because Windows doesn’t support it (mean geek jokes here).

The rebuttal: Windows does support hard-links (since Windows XP and Windows Server 2003). Well, yes, but you can’t hard-link a directory, and hard-links tend to be 1) a security issue and 2) a mess with concurrent access.

The sad/happy truth: Windows not only supports hard-links, but it does support symbolic links as well. The most well known one is “C:\Documents and Settings” (although that one is almost different).

I didn’t even try to research that such a thing exists if it wasn’t for Bogdan, who kindly sent me a day later a usage scenario for the utility mklink, of which I knew nothing about. So here it is:

The whole story: Windows supports symlinks since Windows Vista and Windows Server 2008. This is available for NTFS only (but seriously, FAT is for floppy disks, I hope people stopped using that some decades ago). This piece of information is very little known, and it’s definitely worth spreading the word about it, since symlinks are useful and fun to use (for developers).

Symlinks for files are as straight forward as links in UNIX environments, and they are created by adding no switches to the mklink command (the symlink being the default).

[code]04/27/2013 09:51 AM 1,126 temp.txt
04/27/2013 09:51 AM <SYMLINK> temp2.txt [temp.txt][/code]

In fact, even cygwin sees these links, as expected, when using ls for example:

[code]-rwx——+ 1 Administrators None 1126 Apr 27 09:51 temp.txt
lrwxrwxrwx 1 Administrators None 8 Apr 27 09:51 temp2.txt -> temp.txt[/code]

Cool. What else? You can link directories, of course, and this is demonstrated by the “Documents and Settings” folder. You can use the /D switch of mklink. However, you can also make directory junctions, and this is an interesting flavor of symlink.

The difference between directory junctions and symlinks is that the directory junction is resolved on the server side, not on the client side. This difference is important only when accessing remote files, otherwise directory junctions and symlinks are exactly the same thing.

But when accessing remote files, the difference is important. Let’s say you have a machine, Alpha, that has the remote accessible folder c:\public, and the folders c:\public\linked that links to c:\public\target. If you try to access from Beta the \\Alpha\Public\linked you will be pointed to:

  • C:\public\target on Beta when using a symlink (the resolving of the symlink is done on the client side, the client being Beta).
  • \\Alpha\Public\target when using a directory junction.

What’s the UNIX equivalent? None, because basically you can’t address something without mounting, and when you do, it’s all homogeneous: one filesystem to rule them all, one filesystem to find them, one filesystem to bring them all and in the darkness bind them. You don’t get the privilege of knowing that something is remote, only the backlash (slow access and painful bugs). Thus, all you can do is have relative links.

On the API level, you have the CreateSymbolicLink call which is fairly straight forward. Probably this is a wrapper to the CreateFile call, which, programmers well know, it’s the only real system-call in Windows (and probably the Microsoft guys contemplated on changing the name of CreateFile into “MicrosoftWindows®”, except that it would be so damn hard to type it).

But what is a symlink, after all? A symlink is a text file that has a special flag set in the filesystem to indicate that it should not be opened directly, and it contains the name of the file (or folder) it points to. When you access it, the OS sees the special flag on the file, and instead of opening the file you requested, it will do the operation on the file name that it reads from the symlink.

Comments are closed.