Skip navigation.

Syndicate

Syndicate content

User login

.NET File APIs Don't Like '\\?\' Prefix!?

I’ve recently run into a situation in which I need to use .NET file I/O APIs like File.Exists and File.OpenRead using a filename of the form:

\\?\Volume{guid}\foo.txt

Where guid is a GUID in the standard registry format. Assuming the path refers to a currently available volume (as reported by, for example, mountvol), this is a fully valid path. Try this experiment:

Go to a command prompt, and type mountvol:

The output you’ll get, after usage information, will be the list of current mount points for each mounted volume on your system (in other words, drive letters):

\\?\Volume{88370110-213a-11db-9fa6-806e6f6e6963}\
    C:\

\\?\Volume{9ab4d54b-2171-11db-a24c-005056c00008}\
    G:\

\\?\Volume{6f7fdfc2-213b-11db-9f17-806e6f6e6963}\
    D:\

\\?\Volume{2d206468-216c-11db-9f1d-505054503030}\
    E:\

\\?\Volume{9ab4d552-2171-11db-a24c-005056c00008}\
    F:\

This gives you the volume name corresponding to each local disk drive letter on your system. Now, say you have a file on C:\\, C:\Test.txt. Run this command:

notepad \\?\Volume{88370110-213a-11db-9fa6-806e6f6e6963}\test.txt

Where the GUID junk there is the GUID assigned to your C: drive. If you did it right, notepad will open the file, just as though it was on C:. Note that Explorer doesn’t work with these paths, and neither do the File Open common dialogs. But, if you pass a path like this to CreateFile, as notepad does when you pass a filename on the command line, it will work just like any other file.

However, pull that stunt with a .NET file API, and you’ll get a nice little exception to the tune of Illegal characters in path. What invalid character? Well, for one, the ‘?’ is frowned upon; I don’t think .NET supports the path parsing disabled form of paths at all. I was lucky in that all I needed to do was test for the existence of a specific file with a volume path, so I just did a P/Invoke call to GetFileAttributes. If I’d wanted to read or enumerate such files, I’d be screwed to the wall.

Yes, yes, C/C++ pugilists, rub it in. Basque in this rare instance in which your Win32 API elitism and garbage collector condescension are in fact vindicated. Take a few minutes and savor it; in that time I’ll construct a scalable three-tier web app with authentication, membership, and skinning using a few lines of ASP.NET code, and then you can return to the back of the bus.