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

Reply via email to