Long Filenames on Windows

Argomenti vari di carattere sistemistico
Post Reply
daniele
Posts: 342
Joined: 04 Mar 2009, 13:59

Long Filenames on Windows

Post by daniele »

Articolo originale: http://www.ratsauce.co.uk/notablog/LongFileNames.asp
(All rights reserved to the author of the original article)


Quoting for the Visual C++ documentation for the CreateFile function:

pFileName

Points to a null-terminated string that specifies the name of the file, pipe, mailslot, communications resource, disk device, or console to create, open, or truncate.

If *lpFileName is a path, there is a default string size limit of MAX_PATH characters. This limit is related to how the CreateFile function parses paths.

You can transcend this limit and send in paths longer than MAX_PATH characters by calling the wide (W) version of CreateFile and prepending "\\?\" to the path. The "\\?\" tells the function to turn off path parsing. This lets you use paths that are nearly 32k Unicode characters long. You must use fully-qualified paths with this technique. This also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\tom_1\hotstuff\coolapps" is seen as "\\tom_1\hotstuff\coolapps".

Let me convert this into normal English.

Every Windows program that reads or writes files uses a function called CreateFile privided by Windows. Only programmers need to worry about the details. For our purposes the important thing is that the first parameter passed to the function is the name of the file, and this name has a limit of MAX_PATH characters. MAX_PATH is a constant that Windows defines to be 260, so you can't have file names longer than 260 characters.

Well actually you can. When your program, whether it's a big app like Microsoft Word or a humble xcopy, calls the CreateFile function Windows does various checks on the filename you've supplied before it opens the file. The limit of 260 characters lies in this processing. It isn't a fundamental part of Windows. You can prevent Windows from doing these checks simply by using a fully qualified filename, i.e. starting with the drive letter, and prefixing the filename with "\\?\". When CreateFile sees a filename starting "\\?\" it does not attempt to check the filename and instead just opens the file.

So for example:

del C:\temp\thisnameislongerthen260characters...etc.txt
will report an error, but

del \\?\C:\temp\thisnameislongerthen260characters...etc.txt
will work.

Actually my example is a little askew because "del" doesn't use the CreateFile function. It uses another Windows function, DeleteFile, to delete the file. The trick of prefixing filenames with "\\?\" works with the DeleteFile function as well, and in fact works with all functions that take filenames.

However not applications will accept names prefixed with "\\?\". For example xcopy won't, which is particularly annoying when you're trying to copy directory trees containing long filenames. There's no way to tell which apps accept long filesnames and which apps won't except by trying it.

There is another use for the "\\?\" trick that isn't related to the length of the filename. Normally you can't have a filename with a space at the end. However some apps can create such files, for example Services for Macintosh. If you have a file with a space at the end you won't be able to delete or rename it using Explorer. However you can do this from a command prompt simply by using del or ren and prefxiing the file name with "\\?\". All in all it's a very useful trick to know about.

John Rennie
17th May 2009
Post Reply