[fpc-pascal] DoDirSeparators and special filenames on Windows

Bart bartjunk64 at gmail.com
Sat Sep 7 12:52:13 CEST 2013


Hi,

This is a folowup off a discussion in LazarusDev mailinglist.
It concerns "sanitizing" filenames on the Windows platform.

The Windows API for handling filenames in most cases happily accepts
filenames that have '/' in them. It treats '/' as a pathdelimiter.
It also is very forgiving in using double pathdelimiters.
So, filenames like 'C:\//\\foo/\bar' are treated as 'C:\foo\bar'

So far so good.
There is an exception though: filenames that start with '\\?\' are
considered to be literal and treated as such by the WinAPI.

So if you try to open '\\?\C:\foo/bar'  it will fail, because it
treats the '/' as being part of the filename.
Note that '//?/C:/foo/bar' in contrast happily opens 'C:\foo\bar'
(nice touch from M$).

Note that prepending filenames with '\\?\' is necessary to open files
with names (fully qualified path) longer tham MAXPATH characters.
So in real life your progrmam may need to use this filenaming scheme.

Some of the fpc filehandling functions call DoDirSeparators on the filename.
(ExpandFilename is one of them).
DoDirSeparators transforms '\\?\C:/foo/bar' into '\\?\C:\foo\bar'

This can lead to strange results where e.g FileExists(Filename)
returns FALSE, and FileExists(ExpandFilename(Filename)) returns TRUE,
given that FileName = '\\?\C:/foo/bar' and a file 'C:\foo\bar' exists.

My question is: should DoDirSeparators handle this case and leave the
filename untouched if it starts with '\\?\', or should we leave it up
to the programmer not calling functions like ExpandFilename if a
filename starts with '\\?\'

Note: if you want to test what windows does with '/' , '/\' , '\\?\'
or even '//?\' don't rely on typing this into Explorer or a console.
These do not understand this. You must test the WinApi itself.

Bart



More information about the fpc-pascal mailing list