• problems with qualifying a user-provided path - are there functions ava

    From R.Wieser@21:1/5 to All on Thu Nov 26 12:01:06 2020
    Hello all,

    Using XPsp3 with its standard DLLs (kernel32, shlwapi, etc) :

    I'm trying to make sure that a user-provided path is actually usable, and
    I've run into a problem: I can't seem to find DLL functions which do that.

    As I need an absolute path I've been trying to use GetFullPathName
    (kernel32), but it doesn't even bother to check if the result is
    syntactically correct - feeding it something like "file: //
    d:\folder\file.ext" (spaces not included) makes it return comething like "d:\currentpath\file:\d:\folder\file.ext", which is absolutily bogus.

    I thought that PathSearchAndQualify (shlwapi) would do the trick, but that internally just calls GetFullPathName (I've disassembled the function), and thus does not honor its "AndQualify" name in the least. :-(

    As a work-around I've been using PathFileExists (shlwapi), but although that works it accepts relative paths - and I could not find a function which
    would check if the path is absolute (starts with a driveletter, network
    server, etc.).

    To make things even more interresting, I would also like to be able to
    qualify things like "%temp%\file.ext" and "D:\%username%\file.ext"

    tl;dr:
    How do I qualify a path using the standard DLLs functions (read: not trying
    to check for all bad cases myself) ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Fri Nov 27 08:38:48 2020
    On Thu, 26 Nov 2020 12:01:06 +0100, R.Wieser wrote:
    Hello all,

    Using XPsp3 with its standard DLLs (kernel32, shlwapi, etc) :

    I'm trying to make sure that a user-provided path is actually usable, and I've run into a problem: I can't seem to find DLL functions which do that.

    As I need an absolute path I've been trying to use GetFullPathName (kernel32), but it doesn't even bother to check if the result is syntactically correct - feeding it something like "file: // d:\folder\file.ext" (spaces not included) makes it return comething like "d:\currentpath\file:\d:\folder\file.ext", which is absolutily bogus.

    I thought that PathSearchAndQualify (shlwapi) would do the trick, but that internally just calls GetFullPathName (I've disassembled the function), and thus does not honor its "AndQualify" name in the least. :-(

    As a work-around I've been using PathFileExists (shlwapi), but although that works it accepts relative paths - and I could not find a function which
    would check if the path is absolute (starts with a driveletter, network server, etc.).

    To make things even more interresting, I would also like to be able to qualify things like "%temp%\file.ext" and "D:\%username%\file.ext"

    tl;dr:
    How do I qualify a path using the standard DLLs functions (read: not trying to check for all bad cases myself) ?

    For me, I simply use `GetLongPathName()`. It will fail if the target path is inaccessible, but if there's other better suited function without actually checking the physycal file system object, the path will still point to an inaccessible object anyway.

    If the input path may contain environment variables, I'd process it with `ExpandEnvironmentStrings()` before passing it to `GetLongPathName()`. But
    only if `GetLongPathName()` alone fails with an error stating that the
    target path is not found.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Fri Nov 27 09:39:46 2020
    JJ,

    For me, I simply use `GetLongPathName()`.

    Thats not really usable I'm afraid, as it only replaces the file/folder
    names, and leaves everything else alone. IOW, if you get a non-zero result
    the returned path is valid, but can still be relative and/or contain "." and ".." stuff.

    Lolz : it returns "C:\Windows\System32\..." (thats three (or more!) dots) as valid, but "C:\Windows\System32\...\config.sys" as invalid. Go figure.

    If the input path may contain environment variables, I'd process
    it with `ExpandEnvironmentStrings()` before passing it

    Yup, thats what I'm curently doing. I don't quite like the resulting code-fumbling though. And I still do not see a way to check if the path is absolute.

    Among others I tried PathIsRelative (shlwapi), but thinks that a path
    without a drive but starting with a backslash is absolute ... PathSkipRoot doesn't want to skip the drive infront of a relative path (like "c:folder").

    grumble, grumble, grumble ... :-)

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Sat Nov 28 08:55:58 2020
    On Fri, 27 Nov 2020 09:39:46 +0100, R.Wieser wrote:

    Lolz : it returns "C:\Windows\System32\..." (thats three (or more!) dots) as valid, but "C:\Windows\System32\...\config.sys" as invalid. Go figure.

    You're right. It's unreliable. :(

    Among others I tried PathIsRelative (shlwapi), but thinks that a path
    without a drive but starting with a backslash is absolute ... PathSkipRoot doesn't want to skip the drive infront of a relative path (like "c:folder").

    I haven't checked, but SHELL32's `PathResolve()` seems worth a try. It's defined in `shlobj.h`.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sat Nov 28 07:44:44 2020
    JJ,

    I haven't checked, but SHELL32's `PathResolve()` seems worth a try.

    I had, based on its name, the same idea. Alas, MSDN (docs.microsoft.com)
    seems to have thrown all documention about it away. :-(

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Sun Nov 29 13:03:06 2020
    On Sat, 28 Nov 2020 07:44:44 +0100, R.Wieser wrote:

    I had, based on its name, the same idea. Alas, MSDN (docs.microsoft.com) seems to have thrown all documention about it away. :-(

    But "PathResolve" is the first entry of Gugle, DuckDuckGo, as well as docs.microsoft.com search results. (O.o)?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Nov 29 10:10:14 2020
    JJ,

    But "PathResolve" is the first entry of Gugle, DuckDuckGo, as
    well as docs.microsoft.com search results. (O.o)?

    And to add insult o injury, I actually saved that docs.microsoft.com page.
    :-( My apologies. I must have mixed it up with another similar function.
    Ah yes, there it is : PathQualify

    It doesn't change anything though, as I discarded the PathResolve function (which might be why I misremembered it) because it bungles up as well as not doing its work :

    Mind you, the (console, testing) program is ran from a folder on the the D: drive.
    "+" means ok, "-" means fail.
    ----
    Src:'Hello.vbs'
    - 'Hello.vbs' ;Fail
    ----
    Src:'.\Hello.vbs'
    + 'C:\Hello.vbs' ;Fail, twice.
    ----
    Src:'\Hello.vbs'
    + 'C:\Hello.vbs' ;Fail
    ----

    Also, remember those triple (or more) dots ? Those do not get the function
    to fail either.
    ----
    Src:'files\....'
    + 'C:\files\....'
    ----
    Src:'files\...\file.ext'
    + 'C:\files\...\file.ext'
    ----

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Sun Nov 29 21:29:10 2020
    On Sun, 29 Nov 2020 10:10:14 +0100, R.Wieser wrote:

    Mind you, the (console, testing) program is ran from a folder on the the D: drive.
    "+" means ok, "-" means fail.
    ----
    Src:'Hello.vbs'
    - 'Hello.vbs' ;Fail
    ----
    Src:'.\Hello.vbs'
    + 'C:\Hello.vbs' ;Fail, twice.
    ----
    Src:'\Hello.vbs'
    + 'C:\Hello.vbs' ;Fail
    ----

    Also, remember those triple (or more) dots ? Those do not get the function to fail either.
    ----
    Src:'files\....'
    + 'C:\files\....'
    ----
    Src:'files\...\file.ext'
    + 'C:\files\...\file.ext'
    ----

    All those seems-to-cover-all PathXXX functions... None of them can do the
    most basic thing. How shameful and hilarious.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Nov 29 18:15:50 2020
    JJ,

    All those seems-to-cover-all PathXXX functions... None of them
    can do the most basic thing. How shameful and hilarious.

    Including GetFullPathName and GetLongPathName, yes. And mind you, some of those PathXXX functions have *qualify* in their names ... :-(

    Wat I'm currently doing is using ExpandEnvironmentStrings. If that
    /doesn't/ expand anything I'm giving it to GetFullPathName (which can make a mess). After that I use PathSkipRoot (which does seem to do a decent job),
    and than check the remainder for certain illegal (combination of) chars.

    Though without having documentation on what MS thinks are legal paths I have
    to throw testpaths at functions to see how they respond, and take my clues
    from there.

    And this morning I realised I had almost forgotten about Alternate Data Streams, the names of which get appended to the filepath using the, normally forbidden outside of a drive prefix, colon character ...

    Somehow I don't think that MS really bothered with actually checking if the syntax of a filepath is correct. Instead they seem to have just left it up
    to functions which actually needed the paths to open files (or devices,
    pipes, etc) to error-out on the malformed ones.

    Why is it that I always seem to run into these kind of "must be simple, but isn't" problems ? :-\


    By the way: Did you know that there also isn't any function that checks if a filepath points at a disk/storage-medium file ? I looked for it, but could not find any either.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Mon Nov 30 15:33:45 2020
    On Sun, 29 Nov 2020 18:15:50 +0100, R.Wieser wrote:

    And this morning I realised I had almost forgotten about Alternate Data Streams, the names of which get appended to the filepath using the, normally forbidden outside of a drive prefix, colon character ...

    That actually depends on the file system. e.g. file system other than NTFS
    and ReFS.

    And in terms of NTFS, you've only discovered 66% of it. There's a third
    colon usage to separate between stream name, and NTFS attribute (read: metadata) name. Metadata such as $INDEX_ALLOCATION, $SECURITY_DESCRIPTOR, $DATA, $REPARSE_POINT, $ATTRIBUTE_LIST, etc. However, they are not commonly used, and not normally accessible. They can only be used when a
    file/directory is opened with FILE_FLAG_BACKUP_SEMANTICS. I actually use it
    for my own defragmenter tool. Some example paths would be e.g.

    d:\dir\file.ext:stream:$ATTRIBUTE_LIST
    d:\dir\subdir::$INDEX_ALLOCATION

    Somehow I don't think that MS really bothered with actually checking if the syntax of a filepath is correct. Instead they seem to have just left it up to functions which actually needed the paths to open files (or devices, pipes, etc) to error-out on the malformed ones.

    Why is it that I always seem to run into these kind of "must be simple, but isn't" problems ? :-\

    I could only guess that they think that it's not worth it, considering that
    the validity of a file system path depends on the type of the file system - which can not be retrieved from the path name string alone. Or they're just being lazy.

    By the way: Did you know that there also isn't any function that checks if a filepath points at a disk/storage-medium file ? I looked for it, but could not find any either.

    GetDriveType(), QueryDosDevice(), and GetVolumeInformation(); if the input
    is a mere path name. But the functions may require that the path is already valid, and must point to an existing storage; considering that they may have
    to check some other things.

    There are more options if the input is a file/directory/disk handle.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Nov 30 12:54:28 2020
    JJ,

    That actually depends on the file system. e.g. file system other
    than NTFS and ReFS.

    Ackk, I did not even think of that ...

    And in terms of NTFS, you've only discovered 66% of it. There's
    a third colon usage to separate between stream name, and NTFS
    attribute

    :-) That I did remember.

    Why is it that I always seem to run into these kind of "must be
    simple, but isn't" problems ? :-\

    I could only guess that they think that it's not worth it, considering
    that the validity of a file system path depends on the type of the file system - which can not be retrieved from the path name string alone.

    I can imagine that, as well as the danger of a two filter, pass-nothing
    effect. But then why did they have to use "qualify" in several functions ? Thats just nasty.

    GetDriveType(), QueryDosDevice(), and GetVolumeInformation();

    Thats good for a storage medium, device and again storage medium. Not much help for a file. I can also imagine that the latter two won't work on a network drive ...

    There are more options if the input is a file/directory/disk handle.

    I tried that some time ago. There are (unwanted) side-effects when opening
    a device or pipe.

    One of those other "should be simple, but isn't" problems ...

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)