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. > Otherwise the GetFileAttributes call from the old code needs to be > restored to the new version. > > A few other tiny things: > > (1) > I tested on a directory that has an unsupported reparse tag. > FindFirstFileW fails with ERROR_CANT_ACCESS_FILE (1920) which currently > becomes EIO. The old dirent code fails with EINVAL at readdir (not at > opendir). That is fine. > I guess EIO isn't the best. Directory symlinks and junctions whose > targets don't exist make opendir fail with ENOENT, so I guess it's > appropriate here too. > > A non-directory with an unsupported reparse tag or AF_UNIX were already > ENOTDIR. > > (2) > ERROR_CANT_RESOLVE_FILENAME (1921) is currently mapped to ELOOP. The > error 1921 is possible in situations other than symlink loops too, for > example, a junction with weirdly broken substitute path. > > stat() uses ENOENT in these situations. open() uses EINVAL (if the > reparse point isn't a directory). I suppose EINVAL is a generic > fallback value in MS CRTs, because EINVAL seems to occur with so many > types of errors. > > MSVCRT's strerror(ELOOP) returns "Unknown error". UCRT has a proper > message for ELOOP. Older msvcr* versions probably do not support ELOOP. It could be fixed by introducing a wrapper into mingw-w64 which adds the missing translation. > I'm unsure which is better, ELOOP or ENOENT. Probably it doesn't matter > much in practice. > > (3) > I found old Microsoft docs on the web which, if they can trusted, say > that WC_NO_BEST_FIT_CHARS isn't available on Win95 and NT4. That is truth. I think that I have already mentioned it. Official doc: https://web.archive.org/web/20070224052921/http://msdn.microsoft.com/library/en-us/intl/unicode_17si.asp https://web.archive.org/web/20070320075443/http://msdn.microsoft.com/library/en-us/intl/unicode_2bj9.asp For detection if WC_NO_BEST_FIT_CHARS is not supported, you can do: #ifdef __i386__ WORD version = LOWORD(GetVersion()); version = ((WORD)LOBYTE(version) << 8) | HIBYTE(version); if (version < 0x0410 /* pre-Win98 */) { /* WC_NO_BEST_FIT_CHARS not supported */ } #endif Something like this I have prepared for _acmdln/__getmainargs fixes. > So in the > current form, the new dirent code requires Windows 2000 or later. From > earlier discussions I got an impression that as long as it works on > WinXP it's good enough, so I only updated the comments. > > https://www.tenouk.com/ModuleG.html > > (4) > WideCharToMultiByte docs say that with CP_UTF8 the only supported flag > is WC_ERR_INVALID_CHARS and the last argument must be NULL. It's true on > Win7, but on recent Win10 it works. It's logical because that > combination works with CP_ACP when ACP is UTF-8. This feature seems to > be undocumented, so it's still best to not take advantage of it. > > (5) > In setlocale docs section "UTF-8 support"[1], the last paragraph says > that UTF-8 locales are possible on Windows versions older than 10 with > app-local deployment or static linking of UCRT. I hope this is > irrelevant in mingw-w64 context. Static linking of msvcrt or ucrt is not possible at all. mingw-w64 header files are not aligned for such thing. App-local deployment should be possible. Just would require to prepare manifest and copy all DLLs. More work but I think nothing which mingw-w64 could prevent or could disallow. > In [2] section "Central deployment", > the UCRT versions listed for pre-Win10 are too old to support UTF-8 > locales. The last UCRT redistributable for WinXP has 10.0.10586.15. > > WinXP doesn't support WC_ERR_INVALID_CHARS (Vista does). If someone > managed to use a new enough UCRT on WinXP *and* use a UTF-8 locale, > then the new dirent code doesn't work. > > [1] > https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-170#utf-8-support > > [2] > https://learn.microsoft.com/en-us/cpp/windows/universal-crt-deployment?view=msvc-170#central-deployment > > I attached a patch that adds ERROR_CANT_ACCESS_FILE (1920) and tweaks a > few comments. I didn't change ELOOP. If nothing above made you think > that something else should be changed, then this should finally be the > final version. :-) Thanks! > > -- > Lasse Collin _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
