Why is a drive letter permitted in front of UNC paths (sometimes)?


A little-known quirk is that the file system accepts and ignores a drive letter in front of a UNC path. For example, if you have a directory called \\server\share\directory, you can say

dir P:\\server\share\directory

and the directory will be listed to the screen. The leading P: is ignored.

Why is that?

Rewind to 1984 and the upcoming release of MS-DOS 3.1, which added networking support. Up to this point, all fully-qualified file specifications consisted of three components: A drive letter, a path, and a file name. Many programs relied on this breakdown and did things like "helpfully" prepend a drive letter if it looks like you "forgot" one. For example, if you told it to save the results to \\server\share\file.txt it would say, "Oh dear, that's not good, the user forgot the drive letter! I'll put the current drive in front to make things better," resulting in C:\\server\share\file.txt. Other programs would prompt you with "Please enter a drive letter", and you couldn't say "No, there's no drive letter, just take the path and use it." They insisted on a drive letter, and you darn sure better give them one.

(Compare the Unix programs that "helpfully" rewrite //server/volume/file as /server/volume/file because they "know" that consecutive slashes collapse, unaware of the special exception for two leading slashes.)

In order to retain compatibility with programs that provided this sort of "unwanted help", the designers of the networking support in MS-DOS decided to allow the strange syntax C:\\server\share\directory and treat it as if the drive letter simply weren't there. Some (but not all) of this quirk of path parsing persists today.

[Raymond is currently away; this message was pre-recorded.]

Comments (19)
  1. Stu says:

    But MS-DOS doesnt support UNC paths! Its up to the app to support them and if the app has made the effort to support UNC paths then why would it not understand them when entere? You can’t just pass a UNC path to DOS’s open() call and expect it to work.

    Similarly with UNIX, it’s up to the app to support UNC paths, and where they do, they usually prepend it with a protocol specifier anyway, eg. smb://server/share/file.txt.

    Anyways, I suspect the real reason is that the implementors didn’t want to rewrite all the path manipulation functions, such as .. expansion and the like, so they just took the path (sorry!) of least resistance.

  2. Andreas Häber says:

    This doesn’t work everywhere in DOS:

    $ cd g:\servershareusername

    Systemet finner ikke angitt stasjon.

    $ dir g:\servershareusername

    Volumet i stasjon \servershare er SHARE

    Volumserienummeret er XXXX-YYYY

    Innhold i \servershareusername



    (using Windows XP SP2, and since you like languages you can make a guess which version it is :))

  3. A says:

    "A little-known quirk is that the file system accepts and ignores a drive letter in front of a UNC path."

    On NT-based Windows, it’s only cmd.exe that accepts this syntax (and only in DIR commands, it appears). APIs like CreateFile and FindFirstFile ignore the second backslash.

  4. E says:

    <i>Similarly with UNIX, it’s up to the app to support UNC paths, and where they do, they usually prepend it with a protocol specifier anyway, eg. smb://server/share/file.txt.</i>

    Why should each app need to know about every file access protocol? That’s madness.

    No, the Unix way would be a magic mount point like /smb for all SMB paths: /smb/server/share/file.txt. This is consistent with the "everything’s a file" philosophy (e.g., devices are addressed by /dev/devicename, processes by /proc/pid on Linux) and doesn’t require new path formats (like the double-whack in Windows SMB paths), which breaks lots of things (as Raymond points out). A special exception for two leading slashes is unnecessary (and needlessly hardcoded to SMB).

  5. "A special exception for two leading slashes is unnecessary (and needlessly hardcoded to SMB)".

    It may be unnecessary but it’s part of the POSIX spec – 2.2.2.57: "A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner." (Note: Not hardcoded to SMB.)

  6. Adam G says:

    <i>Compare the Unix programs that "helpfully" rewrite //server/volume/file as /server/volume/file because they "know" that consecutive slashes collapse, unaware of the special exception for two leading slashes.)<i>

    Two minor quibbles:

    1) The Unix shell will turn \servervolumefile into servervolumefile because is an escape character, and \ is the escape sequence for .

    2) Unix doesn’t have UNC paths or anything like them; as noted above the standard unix way would be to mount the share on some directory and them frob it.

    Speaking as a unix user, I do consider the latter to be something of a shortcoming, but there’s nothing really wrong with the former, I don’t think.

  7. microbe says:

    "(Compare the Unix programs that "helpfully" rewrite //server/volume/file as /server/volume/file"

    Unix has no notion of "//". Filesystems, local or remote, could be mounted anywhere. Apps don’t have to know. There is only one single unified namespace.

    Compare to the Windows way, that is obviously superior.

  8. James Antill says:

    As raymond says, the double leading slashes are part of POSIX … however this is a difference between "std. POSIX" and what everyone implements. No mainstream Unix uses this part of POSIX, and so no application worries about it.

    As for applications dealing directly with URLs like smb://… or webdav://… it’s starting to happen through libraries, mainly being pushed by the Desktop framework projects.

  9. That’s what’s so great about standards: Only Microsoft gets called on the carpet for not supporting them. (For what it’s worth, I used a unix that implemented that part of Posix and programs that ignored that rule caused me much grief.)

  10. BryanK says:

    Well, this is how Linux does it (with the kernel SMB client, and Samba’s mount.smbfs binary installed)

    mount -t smbfs //server/share /mnt/share

    ls /mnt/share

    Once it’s mounted, nothing has to worry about the double slashes, and the mount.smbfs binary knows not to "helpfully" collapse "//" into "/".

    The equivalent of UNC paths (not mounting the share anywhere) is usually done by the desktop’s chosen file browser (smb://wherever/whatever/file), as has been pointed out before.

  11. Dewi Morgan says:

    "That’s what’s so great about standards: Only Microsoft gets called on the carpet for not supporting them."

    I disagree: any closed-source OS provider will get "called to the carpet" by their users if they make it impossible to comply with those standards.

    With an open source system like Linux, there’s no "impossible": the user has the luxury of being able to MAKE their OS comply.

    Personally, I feel that the most important part of the title question "Why is a drive letter permitted in front of UNC paths (sometimes)?" is the parenthetical part: why isn’t the ability available consistently, at an OS level?

    Come to that, why not allow any arbitrary URI? After all, "D:\hostpathfile" seems to simply be a URI, with single-letter protocols defined as being the same as the default.

  12. MS-DOS doesn’t support UNC Paths? Wow, I wonder what Aaron Reynold was doing…

    The MS-DOS path canonicalization logic absolutely DID support UNC paths. Now you needed a network filesystem to take advantage of them, but the operating system absolutely did support them.

  13. Andrew Nonymous says:

    You know, if Aaron Reynolds had a blog, it would be the best page on the internet.

    Not just the technical stuff which would be fascinating, the idea of AARD vs hoards of Linux trolls would absolutely kick ass. He could have a non fatal warning at the top if you viewed it with an untested browser.

  14. I think \serverpathfile would be expanded to serverpathfile due to escaping. Let me check in CygWin:

    $ echo \serverpathfile

    serverpathfile

  15. Daniel Berger says:

    Looks like the PathIsUNC() function returns false on UNC paths with drive letters. Bug or feature? :)

  16. Nick Lamb says:

    “That’s what’s so great about standards: Only Microsoft gets called on the carpet for not supporting them. (For what it’s worth, I used a unix that implemented that part of Posix and programs that ignored that rule caused me much grief.)”

    Not only is this sour grapes, it’s not even true, it wouldn’t have taken long to find mentions in GNU bug reports and the associated patches for fixing this in several utilities. Everyone gets called on the carpet for not supporting standards, only Microsoft pours so much resource into trying to weasel out of them or rewrite them to favour its own behaviour.

    Personally I think 2.2.2.57 is a mistake and no OS should take advantage of this "implementation dependent" opt-out, but that doesn’t mean portable software should collapse the pathname without a good reason either.

  17. Shog9 says:

    For what it’s worth, both command.com, cmd.exe, and all of the various *nix shells i’ve used differentiate between forward and backward slashes. So all the replies about how \ equates to an escaped backslash on Linux are as correct as they are irrelevant…

    Of course, all my programs are smart enough to convert both forms of slashes into the One True Slash, remove doubles, and helpfully prepend the path to the user’s home directory… :rolleyes:

  18. frontslash says:

    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase

    –> file:///C:/Program Files/Dir/WindowsApplication1.exe

    Although this isn’t a .net forum, can someone answer what the meaning of 3 slashes in an URI is? Is it even a correct URI?

    (funny note: compact framework doesn’t precede path with any protocol/slashes)

  19. Arild Fines says:

    It’s an URL with the hostname left empty. IE, a regular url is protocol://hostname/whatever. For file://, it’s common to leave out the hostname.

Comments are closed.

Skip to main content