On Sunday 23 February 2025 17:46:26 Lasse Collin wrote: > On 2025-02-22 Pali Rohár wrote: > > On Saturday 22 February 2025 18:12:36 Lasse Collin wrote: > > > On 2025-02-22 Pali Rohár wrote: > > > > On Saturday 22 February 2025 16:03:42 Lasse Collin wrote: > > > > > On 2025-02-18 Pali Rohár wrote: > > > > > > On Tuesday 18 February 2025 23:32:54 Lasse Collin wrote: > > > > > > > On 2025-02-18 Pali Rohár wrote: > > > > > > > > Just one test case, can you check that your new readdir() > > > > > > > > function is working correctly on these two paths? > > > > > > > > > > > > > > > > \\?\GLOBALROOT\Device\Harddisk0\Partition1\ > > > > > > > > \\?\GLOBALROOT\Device\HardiskVolume1\ > > > > > > > > > > > > > > These paths don't work with the old dirent. opendir fails > > > > > > > with ENOENT. > > > > > > > > > > > > Perfect, this is then nice improvement, that in new version > > > > > > it is working. > > > > > > > > > > I had made a mistake. I had tested the new code with and > > > > > without \ at the end, but I had tested the old code only > > > > > without. The old code does work when there is \ at the end. I > > > > > hope it is OK that the new code works without \ too, even > > > > > though I guess it's not strictly correct. > > > > > > > > Uff, I'm not sure. As without the trailing \ the above path is not > > > > directory. > > > > > > Right, it's not a directory. > > > > > > The old dirent code calls GetFileAttributes on the path first and > > > only then proceeds to append \* for _findfirst. The new code > > > doesn't call GetFileAttributes at all, so FindFirstFileW is called > > > with \* appended when there isn't a \ or / at the end already. > > > > > > If GetFileAttributes was called, maybe FindFirstFileW wouldn't need > > > to check for as many Windows error codes, but one has to check for > > > a few codes from GetAttributes still. Also, something in the file > > > system can in theory change before FindFirstFileW is called (a race > > > condition). > > > > > > Are there other situations where a path isn't a directory if there > > > isn't a \ at the end? > > > > It can be anything within NT object system which represents some top > > level filesystem object or NT object symlink to filesystem directory. > > OK, thanks. > > It seems that a few other directory readers cheat with this detail: > > - Gnulib's opendir > > - In Cygwin, > > ls '\\?\C:' > > works even without \ at the end, but \\?\GLOBALROOT\... paths don't > work in any form. > > - UCRT64 Python's os.listdir works with \\?\GLOBALROOT\... path with > and without \ at the end. However, it rejects \\?\C: but \\?\C:\ > works. At the same time, os.stat consistently treats these as block > devices or directories depending on if there is a \ at the end.
This happens when people do not know difference and mix things together. Then the result is even larger mess. WinAPI \\?\ has meaning to not do any normalization, so consumer should not add or remove some characters. > The fact that something else does it wrong doesn't mean that it's > necessarily fine to do so. Mixing these path types would be very bad in > stat() or such function. To me it doesn't feel too bad when one is > specifically trying to open a directory to list its contents (like > opendir or Python's os.listdir). > > Having said that, I will try the GetFileAttributesW solution still. > Maybe it has some other minor benefits in error detection (perhaps it > allows shortening the checked error list of FindFirstFileW). This could improve error handling. > > > An alternative would be to call GetLastError() == > > > ERROR_INVALID_FLAGS if WideCharToMultiByte fails and retry with > > > flags = 0. > > > > That is too complicated. > > It's not much more code. I have attached a patch to do that. On Win95, > GetLastError returns ERROR_INVALID_FLAGS (1004), so I assume that this > method works on NT4 too. Uff, that is questionable. Win9x was always different and not followed the true NT based WinAPI. > I have no real clue about UWP apps, but it seems that GetVersion isn't > supported in those. Thus, if UWP compatibility matters, the GetLastError > method should be compatible. It is really not supported? For me it looks like very strict rules. I think that GetVersion* functions are already used in mingw-w64. > AreFileApisANSI doesn't seem to be supported in UWP apps either. I > suppose it could be added to winstorecompat, always returning 1. That could be useful. > https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis > > -- > Lasse Collin _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
