Windows Confidential

Junction Dysfunction

Raymond Chen

What's with those junctions that don't seem to work? Oh, they work all right- just not the way you think.

Windows Vista and Windows 7 take advantage of a file-system feature known as junctions by including junctions to system directories that have legacy names. When you try to navigate to those folders from Explorer or issuea dir command, however, you just get an Access denied error. Clearly, Microsoft created junctions to provide compatibility with applications that disregarded the MSDN guidance and instead hard-coded paths to various well-known file-system locations. Why, then, don't those junctions work when you attempt to use them?

Actually, they do work for their intended purpose—but the intended purpose wasn’t command-line access or navigation from Explorer. To see how we got into this situation, let's rewind the clock about a decade.

In the early days of Windows NT, as it was called, user profiles resided in the C:\WINNT\Profiles directory. And yes, back then the default name for the Windows directory was WINNT. During the development of Windows 2000, security considerations and feedback from corporate customers prompted the developers of the operating system to move the user profiles directory out of the Windows directory so the latter’s security settings could be tightened.

Before the change, the Windows directory—the most important directory in the system—had this island of insecurity in the middle. People who wanted to apply new, stricter security to the entire directory had to tiptoe around the Profiles subdirectory lest they end up accidentally locking all users out of the system. Moving the profiles out of the Windows directory solved the problem.

Relocating the folder provided an excellent opportunity to rename it to something more descriptive. One of the early choices was Documents & Settings, but the ampersand caused a large number of application-compatibility problems. For example, some programs accidentally interpreted the ampersand as a keyboard-accelerator marker and wound up displaying the directory as Documents _Settings (following the convention, used in menus and dialog boxes, of underlining the accelerator key).

Windows 2000 settled on Documents and Settings, which provided a reasonably descriptive name for the directory but failed to take other factors into account. For one, the embedded space made typing the path more cumbersome because of the constant need to apply quotation marks. Also, the sheer length of the name was an obstacle, especially because it cut into the

MAX_PATH

limit for Win32 path names. These and other factors prompted the Windows team to reorganize the various system directories yet again in Vista, and the arrangement carries forward into Windows 7.

When the directories moved the second time, Windows left behind junctions to help applications that had hard-coded paths to these directories when they should have used functions such as

SHGetFolderPath

and

GetProfilesDirectory

(or, if you're a scripting type of person, the

Shell.Application.NameSpace

method we saw back in the November 2005 issue).

If an application tries to access the file

C:\Documents and Settings\username\Start Menu\Programs\Internet Explorer.lnk

the junctions installed at

Documents and Settings

and at

Start Menu

will guide the call to the correct new location, which for a local non-roaming profile is now

C:\Users\username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Internet Explorer.lnk

Naturally, programmers shouldn't hard-code this new location any more than they should have hard-coded the old one—they should use the appropriate functions for determining the locations of well-known folders.

Of course, a new opportunity can create a new problem: An application that isn’t familiar with junctions may get stuck in an infinite loop when it attempts to perform a recursive directory-tree walk. To prevent this, the compatibility junctions permit directory traversal but explicitly deny List contents permission: If you try to navigate to these folders from Explorer or the command prompt, you’ll get an Access denied error.

The compatibility symbolic links grant enough access to accomplish their goal of providing compatibility for older applications that unwisely chose to hard-code directory names. But they don’t supply enough rope to let these older applications cause themselves serious harm. Blocking List contents also has the pleasant side effect of removing an attractive nuisance for new programmers, who may be tempted to continue the tradition of those older applications. Will this technique work to steer people in the right direction? Only time will tell.

 

Raymond Chen*, Raymnond's Web site, The Old New Thing, and identically titled book (Addison-Wesley, 2007) deal with Windows history, Win32 programming, and salty soymilk.*

Windows Confidential: Encoding Is Not Encrypting

Windows Confidential: Windows 'Prettified' Filenames

Windows Confidential: Cached Credentials