[fpc-pascal] DoDirSeparators and special filenames on Windows

Sven Barth pascaldragon at googlemail.com
Sat Sep 7 18:07:27 CEST 2013


Am 07.09.2013 16:19 schrieb "Jürgen Hestermann" <juergen.hestermann at gmx.de>:
> > 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 '\\?\'
>
> In general I would prefer if this '\\?\' prefix is hidden away from the
programmer at all. File names should be just that: File names. On windows
*every* API function that expects file names should be prepended with
'\\?\' internally while for Linux this should be omitted. But the
programmer should not need to know about this. Internal functions that use
WinAPI calls should add the prefix theirself in all cases(!) (if supported)
and omit it for Linux. For all situations where the file name is
moved/converted from one function to another (when no OS-API functions is
involved) it should just leave the name as it is.
>
> I have written my own functions which do this because it is a nightmare
to find out which kind of string encoding is expected/required by what
function within FPC/Lazarus. The documentation just says "string" but never
says whether it is UTF8, UTF16 or whatever. So when I want to be sure what
happens I have to reinvent the wheel and write my own OS independend
functions which in my case *always* expect UTF8 (which is my standard
encoding in all situations) and convert to UTF16 and add the prefix '\\?\'
when feeding it to a WinAPI function:
>
> function WinAPIPathName(const Pfad : UTF8String) : UTF8String;
> begin
> Result := Pfad;
> if (length(Result)<=3) or
>    (Result[1]='\') and
>    (Result[2]='\') and
>    (Result[3]='?') and
>    (Result[4]='\') then exit;
> if (length(Result)>=2) and
>    (Result[1]='\') and
>    (Result[2]='\') then      // UNC-path, i.e. "\\server\share"
>    begin
>    Result := '\\?\UN'+Result;
>    Result[7] := 'C';
>    end
> else
>    Result := '\\?\'+Result;
> end;
>
> which I then call like this:
>
> H  := FindFirstFileW(pwidechar(UTF8Decode(WinAPIPathName(Pathname))),FW);
>
> This way I don't need to bother about path lengths and unicode issues. I
just use UTF8 in my programs. And when I need other encodings I know that I
have to convert them before calling functions that need UTF8.

The "\\?\" paths don't support relative paths and also not all I/O-APIs
support this convention.

In my opinion a programmer needs to know the quirks of the platforms he/she
wants to target.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20130907/20969e88/attachment.html>


More information about the fpc-pascal mailing list